PlanningPME API - Documentación del desarrollador

Interconecte el planning con el resto de su sistema de información.
PlanningPME permite el acceso de lectura y escritura a los datos de la base de datos de sus clientes a través de una API dedicada. La API de PlanningPME cumple con los estándares de desarrollo actuales (implementación de REST e intercambio de datos en formato JSON) para una programación sencilla de sus sincronizaciones e integraciones.

Este documento le informará sobre:

¿Dónde puedo encontrar la dirección de su API de PlanningPME?
¿Cómo acceder a su documentación interactiva?
Implementando seguridad en la API de PlanningPME
¿Cuáles son los hechos generales sobre los datos de la API de PlanningPME?
¿Cómo hacer sus primeras solicitudes a la API de PlanningPME?

La API de PlanningPME está basada en los principios de la API RESTful y el formato de transferencia de datos utilizado es JSON.
Esta documentación es principalmente para desarrolladores. Le recomendamos que lea la API REST de la API de JSON antes de continuar.

URL deseada

Cada cliente PlanningPME tiene su propia dirección de API dedicada.
Supongamos que su marca es "MyCompany", lo más probable es que necesite usar la clave "mycompany" (que no distingue entre mayúsculas y minúsculas) para crear su dirección API.
Esta clave se marcará como " su_marca " en el resto de esta documentación.

La dirección API base de una marca registrada siempre tendrá el formato:
https://api.planningpme.com/su_marca/
o
https://try.planningpme.com/su_marca/

Documentación interactiva

Cada API viene con una documentación interactiva, muy útil para descubrir los métodos y modelos utilizados en la API de PlanningPME, o generar consultas.

Documentación interactiva

Esta documentación está disponible en la siguiente dirección:
https://api.planningpme.com/su_marca/doc/index
o
https://try.planningpme.com/su_marca/doc/index

Estas dos direcciones no se pueden llamar sin presentar una clave de API .

Nota: si la autenticación de cuenta está activada en su API, el acceso a la documentación interactiva está a un clic de distancia dentro de la aplicación de cuenta PlanningPME.

Seguridad

1 / Presentación de la clave API

El acceso a su API requiere una clave que identifique su aplicación y asegure su acceso: una appkey.
Esta appkey está disponible en su cuenta PlanningPME (si la autenticación de cuenta está activada en su API), o a petición del soporte.

La clave de aplicación siempre debe enviarse en el encabezado de una solicitud de API, utilizando el encabezado "X-APPKEY" dedicado.

GET /su_marca/api/config HTTP/1.1
Host: api.planningpme.com
X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac

Para acceder a su documentación interactiva, utilice la appkey como parámetro de dirección, como en el ejemplo siguiente.

https://api.planningpme.com/su_marca/doc/index?appkey=e991573da5ffd4sab9b1e26bc6b64aac

2 / Autenticación y carga de perfil.

La mayoría de las peticiones a la API también deben presentar un token de autorización, con el fin de determinar el perfil del usuario que accede a los datos, y respetar las autorizaciones de usuario y grupo definidas en la aplicación.

Este token se obtiene previamente cuando un usuario se autentica en la dirección /token, y tiene una validez de 8 horas.

Los datos enviados a esta dirección varían en función del modo de autenticación elegido para su aplicación.

a) Autenticación tradicional

Si está activada, la autenticación tradicional se consigue colocando el nombre de usuario y la contraseña.

POST /su_marca/token HTTP/1.1
Host: api.planningpme.com
X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=su_usuario&password=su_contraseña

b) Autenticación de cuenta

Si está activada, la autenticación de la cuenta se consigue mediante posicionamiento de un token de cuenta de servicio, obtenido previamente en la aplicación de cuenta PlanningPME.

API PlannningpmE

Para cada usuario de esta lista, puede copiar el token de la cuenta de servicio en el portapapeles.

Ahora obtenga un token de autorización de su API, colocando el token de cuenta copiado (aserción).

POST /su_marca/token HTTP/1.1
Host: api.planningpme.com
X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=account_token

c) Autenticación de cliente OAuth

Para abrir su API a un socio o a una aplicación de terceros, le recomendamos que cree un cliente OAuth y configure sus tokens de autenticación.

Gestión de su acceso OAuth

Una vez que tenga su identificador y token de cliente OAuth, su tercero podrá autenticarse en la API y obtener un token de autorización de la siguiente manera.

POST /su_marca/token HTTP/1.1
Host: api.planningpme.com
X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&client_id=id_de_client&assertion=jeton_de_client

d) Utilización del token de autorización

En el caso de una autentificación exitosa, el cuerpo de la respuesta contendrá un elemento JSON de la siguiente manera.

{
    "access_token": "KTuZYDLG2qjUMqMVXDuiP9giFbqDXstESvpUWzBFLpkfdlMiB3PD5s2K7En-3o39u56hpr_DlyjEc_...3Is0gcH",
    "token_type": "bearer",
    "expires_in": 86399,
    "username": "su_usuario"
}

La propiedad "access_token" contiene el token de autorización de la API.

Además, como indica la propiedad "token_type", este token es de tipo "bearer". Por lo tanto, las solicitudes que requieran autorización deben presentar la cabecera "Authorization" con el valor "Bearer", como en el ejemplo siguiente.

POST /su_marca/api/customer HTTP/1.1
Host: api.planningpme.com
X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac
Authorization: Bearer KTuZYDLG2qjUMqMVXDuiP9giFbqDXstESvpUWzBFLpkfdlMiB3PD5s2K7En-3o39u56hpr_DlyjEc_...3Is0gcH

Utilización de la API

1/ Generalidades

a) Modelos de datos

Los modelos de datos de PlanningPME se detallan en la documentación interactiva de su API.

b) Formato de fecha

El formato de fecha utilizado por la API y esperado en cada solicitud JSON es el formato ISO 8601 . Ex:

2018-01-25T18:05:00Z

c) orden de lista

Los métodos GET a menudo usan un parámetro " sortInfo " para establecer el orden de clasificación de la lista completa o paginada que se devuelve.

Esta información se compone del nombre de una propiedad seguida directamente por un signo + o -.
Por ejemplo, use " label + " para solicitar una ordenación alfabética ascendente en la propiedad "label".

También es posible combinar varios comandos agregándolos.
Por ejemplo, use " not Valid-label " para solicitar una clasificación descendiendo la propiedad "notValid" y luego alfabéticamente ascendiendo a "label".

Tenga en cuenta que los nombres de propiedades distinguen entre mayúsculas y minúsculas.

d) Constantes de enumeración

Aunque no cambiará, excepto agregar, la lista completa de enumeración utilizada en su versión de API se obtiene llamando al método "/ api / config".

GET /su_marca/api/config HTTP/1.1
Host: api.planningpme.com
X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac

A continuación encontrará la lista de constantes de enumeración. - v4.7.0.28

{
...
"enums": {
	"Access": {
		"All": "All",
		"Read": "Read",
		"Write": "Write"
	},
	"BillingType": {
		"Package": "Package",
		"Unit": "Unit"
	},
	"ColorDepending": {
		"Label": "Label",
		"Category": "Category",
		"Customer": "Customer",
		"Time": "Time",
		"Project": "Project"
	},
	"ConfigType": {
		"ExportTemplates": "ExportTemplates",
		"TimeRestrictedView": "TimeRestrictedView",
		"Filterings": "Filterings",
		"Language": "Language",
		"DateTimeFormat": "DateTimeFormat",
		"GCSync": "GCSync",
		"EffectTemplates": "EffectTemplates",
		"SyncResource": "SyncResource",
		"PrintTemplates": "PrintTemplates",
		"DoSearch": "DoSearch",
		"SwitchLabel": "SwitchLabel",
		"OAuthClients": "OAuthClients",
		"Buttoned": "Buttoned"
	},
	"ConstraintAction": {
		"NoTaskBeforeNbHours": "NoTaskBeforeNbHours",
		"NoTaskBeforeNbDays": "NoTaskBeforeNbDays",
		"NoTaskSamePeriod": "NoTaskSamePeriod",
		"NbMaxHours": "NbMaxHours",
		"NbMax": "NbMax",
		"DurationMaxHours": "DurationMaxHours",
		"DurationMaxDays": "DurationMaxDays"
	},
	"ConstraintFor": {
		"All": "All",
		"Resources": "Resources",
		"Departments": "Departments"
	},
	"ConstraintIf": {
		"Nothing": "Nothing",
		"Nb": "Nb",
		"NbHours": "NbHours",
		"Begin": "Begin",
		"End": "End"
	},
	"ConstraintOp": {
		"Nothing": "Nothing",
		"Equal": "Equal",
		"Inf": "Inf",
		"InfEqual": "InfEqual",
		"Sup": "Sup",
		"SupEqual": "SupEqual",
		"Before": "Before",
		"After": "After"
	},
	"ConstraintType": {
		"Task": "Task",
		"Unavailability": "Unavailability"
	},
	"ConstraintWhat": {
		"LabelAll": "LabelAll",
		"LabelExact": "LabelExact",
		"LabelBegin": "LabelBegin"
	},
	"ConstraintWhen": {
		"Nothing": "Nothing",
		"Day": "Day",
		"Week": "Week",
		"Month": "Month",
		"Year": "Year"
	},
	"CountHolidays": {
		"Five": "Five",
		"Six": "Six"
	},
	"CurrencyCode": {
		"GBP": "GBP",
		"EUR": "EUR",
		"USD": "USD",
		"DEM": "DEM",
		"FRF": "FRF",
		"CHF": "CHF",
		"ARS": "ARS",
		"BRL": "BRL",
		"CLP": "CLP",
		"CRC": "CRC",
		"RUB": "RUB",
		"GTQ": "GTQ",
		"PAB": "PAB",
		"PYG": "PYG",
		"PEN": "PEN",
		"UYU": "UYU",
		"SVC": "SVC",
		"HNL": "HNL",
		"NOK": "NOK",
		"CNY": "CNY",
		"JPY": "JPY",
		"CAD": "CAD",
		"SAR": "SAR"
	},
	"CustomerType": {
		"Individual": "Individual",
		"Company": "Company"
	},
	"DataFieldType": {
		"Date": "Date",
		"Time": "Time",
		"Text": "Text",
		"Numeric": "Numeric",
		"Double": "Double",
		"Combo": "Combo",
		"Link": "Link",
		"Check": "Check",
		"Memo": "Memo",
		"Separator": "Separator",
		"File": "File",
		"Position": "Position",
		"SignatureMobile": "SignatureMobile",
		"Hyperlink": "Hyperlink",
		"ProjectStartDate": "ProjectStartDate",
		"ProjectEndDate": "ProjectEndDate",
		"ProjectDuration": "ProjectDuration",
		"ProjectDeadline": "ProjectDeadline",
		"ProjectDeadlineOver": "ProjectDeadlineOver",
		"Signature": "Signature",
		"ProjectEstimateDuration": "ProjectEstimateDuration",
		"SubProjectEstimateDuration": "SubProjectEstimateDuration",
		"Multi": "Multi",
		"Location": "Location"
	},
	"DescriptionFieldType": {
		"Index1": "Index1",
		"Index2": "Index2",
		"EmailBody": "EmailBody",
		"Label": "Label",
		"Mobile": "Mobile",
		"CalendarBody": "CalendarBody",
		"EmailSubject": "EmailSubject",
		"Tooltip": "Tooltip",
		"LabelAssignment": "LabelAssignment",
		"CalendarSubject": "CalendarSubject",
		"Print": "Print",
		"ToPlan": "ToPlan",
		"LabelUnavailability": "LabelUnavailability",
		"PrintUnavailability": "PrintUnavailability",
		"HeaderCustomer": "HeaderCustomer",
		"CaptionCustomer": "CaptionCustomer",
		"HeaderProject": "HeaderProject",
		"CaptionProject": "CaptionProject",
		"HeaderResource": "HeaderResource",
		"CaptionEquipment": "CaptionEquipment"
	},
	"DescriptionFieldStyle": {
		"Normal": "Normal",
		"Bold": "Bold",
		"Italic": "Italic",
		"Underline": "Underline"
	},
	"DescriptionFieldColor": {
		"Custom": "Custom",
		"Default": "Default",
		"Destination": "Destination"
	},
	"Destination": {
		"Task0": "Task0",
		"Task2": "Task2",
		"Task3": "Task3",
		"Task4": "Task4",
		"Task5": "Task5",
		"Equipment0": "Equipment0",
		"Customer1": "Customer1",
		"Unavailability0": "Unavailability0",
		"MaterialResource1": "MaterialResource1",
		"MaterialResource2": "MaterialResource2",
		"MaterialResource3": "MaterialResource3",
		"Project0": "Project0",
		"HumanResource1": "HumanResource1",
		"HumanResource2": "HumanResource2",
		"Task1": "Task1",
		"HumanResource3": "HumanResource3",
		"Customer0": "Customer0",
		"HumanResource0": "HumanResource0",
		"Customer2": "Customer2",
		"MaterialResource0": "MaterialResource0",
		"Customer3": "Customer3",
		"Project1": "Project1",
		"Project2": "Project2",
		"SubProject0": "SubProject0",
		"Project3": "Project3"
	},
	"DestinationType": {
		"Task": "Task",
		"Customer": "Customer",
		"Equipment": "Equipment",
		"Resource": "Resource",
		"Project": "Project",
		"SubProject": "SubProject",
		"Unavailability": "Unavailability"
	},
	"DoMode": {
		"None": "None",
		"End": "End",
		"Duration": "Duration"
	},
	"EffActionType": {
		"Email": "Email",
		"Sms": "Sms",
		"MicrosoftOutlook": "MicrosoftOutlook",
		"GoogleCalendar": "GoogleCalendar"
	},
	"EffGapUnit": {
		"Minute": "Minute",
		"Hour": "Hour",
		"Day": "Day",
		"Week": "Week",
		"Month": "Month",
		"Year": "Year"
	},
	"EffIfType": {
		"Category": "Category",
		"Status": "Status"
	},
	"EffIfOp": {
		"IsIn": "IsIn",
		"BecomesIn": "BecomesIn"
	},
	"EffSourceType": {
		"Customer": "Customer",
		"Resource": "Resource",
		"Project": "Project",
		"Status": "Status",
		"ResourceIn": "ResourceIn",
		"ProjectIn": "ProjectIn",
		"TaskIn": "TaskIn",
		"Assignment": "Assignment",
		"Unavailability": "Unavailability",
		"Task": "Task"
	},
	"EffStepType": {
		"Start": "Start",
		"End": "End",
		"Insert": "Insert",
		"Delete": "Delete",
		"Unperiodize": "Unperiodize",
		"Update": "Update"
	},
	"EffSubjectType": {
		"Assignment": "Assignment",
		"Unavailability": "Unavailability",
		"Task": "Task"
	},
	"EffTargetType": {
		"Customer": "Customer",
		"Resource": "Resource",
		"User": "User",
		"Account": "Account",
		"Creator": "Creator"
	},
	"HistoryOp": {
		"Insert": "Insert",
		"Delete": "Delete",
		"Email": "Email",
		"Invitation": "Invitation",
		"Unperiodize": "Unperiodize",
		"Session": "Session",
		"Update": "Update"
	},
	"HistoryType": {
		"Assignment": "Assignment",
		"Customer": "Customer",
		"SessionDesktop": "SessionDesktop",
		"Unavailability": "Unavailability",
		"SessionMobile": "SessionMobile",
		"Project": "Project",
		"Resource": "Resource",
		"Task": "Task",
		"User": "User",
		"SessionWebAccess": "SessionWebAccess"
	},
	"InRootType": {
		"Customer": "Customer",
		"Project": "Project",
		"Resource": "Resource"
	},
	"JoinStatus": {
		"Invited": "Invited",
		"Connected": "Connected"
	},
	"JsonWritingType": {
		"None": "None",
		"Normal": "Normal",
		"KeyLabel": "KeyLabel",
		"String": "String",
		"Data": "Data"
	},
	"LicenseStatus": {
		"Other": "Other",
		"Evaluation": "Evaluation",
		"Ok": "Ok",
		"NoExpirationDate": "NoExpirationDate",
		"WrongDatabase": "WrongDatabase",
		"WrongMachine": "WrongMachine",
		"ResourceCount": "ResourceCount",
		"LicenseCount": "LicenseCount",
		"Expired": "Expired",
		"Empty": "Empty",
		"Corrupted": "Corrupted"
	},
	"LinkRefType": {
		"Assignment": "Assignment",
		"Customer": "Customer",
		"Unavailability": "Unavailability",
		"Project": "Project",
		"Resource": "Resource",
		"Task": "Task"
	},
	"NotificationType": {
		"None": "None",
		"TaskInsert": "TaskInsert",
		"TaskUpdate": "TaskUpdate",
		"UnavailabilityInsert": "UnavailabilityInsert",
		"UnavailabilityUpdate": "UnavailabilityUpdate"
	},
	"OneOrMoreCustomers": {
		"OneCustomer": "OneCustomer",
		"MoreCustomer": "MoreCustomer"
	},
	"OneOrMoreResources": {
		"OneResource": "OneResource",
		"MoreResource": "MoreResource"
	},
	"RecurrenceDaily": {
		"AllThe": "AllThe",
		"AllWorkingDays": "AllWorkingDays"
	},
	"RecurrenceMonthly": {
		"Date": "Date",
		"Day": "Day"
	},
	"RecurrenceMonthlyDayWhich": {
		"First": "First",
		"Second": "Second",
		"Third": "Third",
		"Fourth": "Fourth",
		"Last": "Last"
	},
	"RecurrenceRange": {
		"NoEndDate": "NoEndDate",
		"EndThe": "EndThe"
	},
	"RecurrenceType": {
		"Daily": "Daily",
		"Weekly": "Weekly",
		"Monthly": "Monthly",
		"Yearly": "Yearly"
	},
	"ResourceType": {
		"Human": "Human",
		"Material": "Material",
		"ToPlan": "ToPlan",
		"Extern": "Extern"
	},
	"StatusType": {
		"Task": "Task",
		"Unavailability": "Unavailability"
	},
	"SyncType": {
		"_Google": "_Google",
		"Microsoft": "Microsoft",
		"Google": "Google",
		"Lucca": "Lucca"
	},
	"TaskType": {
		"Default": "Default",
		"Duration": "Duration",
		"Time": "Time"
	},
	"Title": {
		"Miss": "Miss",
		"Mr": "Mr",
		"Ms": "Ms"
	},
	"TimeLapseUnit": {
		"Day": "Day",
		"Week": "Week",
		"Month": "Month",
		"Year": "Year"
	},
	"TypeHatch": {
		"BDIAGONAL": "BDIAGONAL",
		"CROSS": "CROSS",
		"DIAGCROSS": "DIAGCROSS",
		"FDIAGONAL": "FDIAGONAL",
		"HORIZONTAL": "HORIZONTAL",
		"VERTICAL": "VERTICAL"
	},
	"WorkCapacity": {
		"Hours": "Hours",
		"Slots": "Slots"
	}
},
...

e) Lenguaje de respuesta

El idioma deseado en los textos de respuesta, como los mensajes de error, se puede especificar en el encabezado " Aceptar-Idioma ".

Aceptar-Idioma: es

Los idiomas disponibles en PlanningPME API y PlanningPME WebAccess son: alemán (de), inglés (en), danés (da), español (es), finlandés (fi), francés (fr), italiano (it), japonés (ja), neerlandés (nl), noruego (no), polaco (pl), portugués (pt), ruso (ru), sueco (sv).

Ejemplos de consulta API

En los ejemplos siguientes, la clave de aplicación utilizada se anota "your_key", y el token de autorización "your_token". Por favor, sustitúyalos por sus propios valores.

/api/task

→  Recupera una lista (completa o paginada) de tareas con el método GET "/ api / task".

GET /su_marca/api/task?pageIndex=1&pageSize=20&sortInfo=label+ HTTP/1.1
Host: api.planningpme.com
X-APPKEY: tu_clave
Authorization: Bearer tu_token

Devuelva la segunda página de veinte tareas en una tabla clasificada en orden ascendente en la etiqueta.

{
  "totalItems": 97,
  "items": [
    {
      "key": 756,
      "label": "Cours d'anglais pour enfant",
      "type": 1467,
      "style": {
        "backgroundColor": "#65A18D",
        "color": "#000000"
      }
    },
	...
    {
      "key": 131,
      "label": "Coaching",
      "type": 1467,
      "style": {
        "backgroundColor": "#214DE9",
        "color": "#000000"
      }
    }
  ]
}

→  Recupere los detalles de una tarea con el método GET "/ api / task / {id}".

GET /su_marca/api/task/756 HTTP/1.1
Host: api.planningpme.com
X-APPKEY: votre_clé
Authorization: Bearer tu_token

Devuelve los detalles de la tarea ID 756.

{
  "key": 756,
  "label": "Cours d'anglais pour enfant",
  "type": 1467,
  "style": {
    "backgroundColor": "#65A18D",
    "color": "#000000"
  },
  "skills": [
    [
      {
        "key": 12,
        "name": "Enfant",
        "label": "Pédagogie > Enfant",
        "level": 1,
        "domain": {
          "key": 4,
          "label": "Pédagogie"
        }
      },
      {
        "key": 83,
        "name": "Anglais",
        "label": "Langue > Anglais",
        "level": 1,
        "domain": {
          "key": 4,
          "label": "Langue"
        }
      }
    ]
  ]
}

/api/oauth

→ Recupere la lista de clientes OAuth utilizando el método GET "/api/oauth/client".

GET /su_marca/api/oauth/client HTTP/1.1
Host: api.planningpme.com
X-APPKEY: tu_clave
Authorization: Bearer tu_token
{
  "totalItems": 2,
  "items": [
    {
      "id": "2bc87bded6bf4de7babe8ea5a9452735",
      "name": "backoffice"
    },
    {
      "id": "1601c39ed33a4c4084750356a7f8d7a5",
      "name": "apptest2"
    }
  ]
}

→ Cree un nuevo cliente OAuth utilizando el método POST "/api/oauth/client".

POST /su_marca/api/oauth/client HTTP/1.1
Host: api.planningpme.com
X-APPKEY: votre_clé
Authorization: Bearer tu_token

{
  "name": "apptest3"
}

Devuelve el cliente creado y su identificador.

{
  "id": "22f37990d2304af3a9e20dc4b05efe26",
  "name": "apptest3"
}

→ Cree un nuevo token OAuth para un cliente dado (en este caso "apptest3") y un usuario dado (en este caso el usuario cuya clave es 99), utilizando el método POST "/api/oauth/token".

POST /su_marca/api/oauth/token HTTP/1.1
Host: api.planningpme.com
X-APPKEY: votre_clé
Authorization: Bearer tu_token

{
  "clientId": "22f37990d2304af3a9e20dc4b05efe26",
  "user": {
    "key": 99
  }
}

Devuelve el token creado, su fecha de caducidad y la aserción vinculada.

Tenga en cuenta que ya no se puede recuperar la aserción completa (propiedad "jwt"). Por lo tanto, es aconsejado ponerlo en un lugar seguro en cuanto se cree.

{
  "id": "63d134cf760940e7af7acf16e4890835",
  "userKey": 99,
  "expirationDate": "2027-05-14T13:11:49.8116664Z",
  "resume": "eyJhbGciOiJodHR...wtO_PkdOFllvyNk",
  "invalid": false,
  "jwt": "eyJhbGciOiJodHRwOi8vd3d3FgdfLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwidW5pcXVlX25hbWUiOiI2M2QxMzRjZjc2MDk0MGU3YWY3YWNmMTZlODk1MDgzNSIsImp0aSI6ImRkOGM0OTZlLTBlZjYtNDQ5MS04MGNkLTM1YzRkODIxMGZlZSIsImlhdCI6MTc0NzIlkj345SwibmJmIjoxNzQ3MjI4MzA5LCJleHAiOjE4MTAzMDAzMDksImlzcyI6Imh0dHBzOi8vYXBpLnBsYW5uaW5ncG1lLmNvbSIsImF1ZCI6IjMzZjM3OTkwZDIzMDRhZjNhOWUyMGRjNGIwNWVmZTI2In0.9f-X_bc4Ca8gTyQ_FZJsAvdH0gkWwtO_PkdOFllvyNk"
}

→ Recupere la lista de tokens vinculados a un cliente OAuth mediante el método GET "/api/oauth/token?clientID={id}".

GET /su_marca/api/oauth/token?clientId=2bc87bded6bf4de7babe8ea5a9212735 HTTP/1.1
Host: api.planningpme.com
X-APPKEY: tu_clave
Authorization: Bearer tu_token
{
  "totalItems": 1,
  "items": [
    {
	  "id": "63d134cf760940e7af7acf16e4890835",
	  "userKey": 99,
	  "expirationDate": "2027-05-14T13:11:49.8116664Z",
	  "resume": "eyJhbGciOiJodHR...wtO_PkdOFllvyNk",
	  "invalid": false
	}
  ]
}