PlanningPME API - Documentação do desenvolvedor
Interligue os seus dados de planeamento com o resto do seu sistema de informação.
PlanningPME permite o acesso de leitura e escrita à sua base de dados através de uma API dedicada.
A API PlanningPME segue o padrão de desenvolvimento actual (implementação REST e transporte de dados em formato JSON) para uma programação simples das suas sincronizações e integrações.
Este documento irá informá-lo sobre o assunto:
Como determinar o seu endereço API do PlanningPME ?Onde encontrar a sua documentação interactiva ?
Como é implementada a segurança no PlanningPME API ?
Quais são as considerações de dados comuns no PlanningPME API ?
Como fazer os seus primeiros pedidos ao PlanningPME API ?
PlanningPME API é baseado em RESTful princípios, e o formato padrão de transferência de dados é JSON.
Esta documentação é principalmente para programadores. Recomendamos que o leitor se familiarize com a programação JSON REST API antes de ir mais longe.
URL dedicado
Cada cliente PlanningPME tem o seu próprio endereço API dedicado.
Digamos que o seu nome de marca é "MyCompany", deverá provavelmente utilizar a chave de marca "mycompany" (ignorando o caso) para construir o seu endereço API.
Esta chave será anotada como "seu_marca" no resto desta documentação.
O endereço API de base de uma marca será sempre :
https://api.planningpme.com/a sua_marca/
o
https://try.planningpme.com/a sua_marca/
Documentação interactiva
Cada API de marca também apresenta uma documentação interactiva, muito útil para descobrir os seus métodos e modelos de API PlanningPME e construir chamadas API.

Esta documentação está disponível no seguinte endereço :
https://api.planningpme.com/a sua_marca/doc/index
o
https://try.planningpme.com/a sua_marca/doc/index
Estes dois endereços não podem ser chamados sem apresentar uma chave de aplicação.
Nota: se a autenticação da conta estiver activada na sua API, o acesso à documentação interactiva está à distância de um clique na aplicação da conta PlanningPME.
Segurança
1/ Apresentação da chave de aplicação
O acesso à sua API requer uma chave que identifique sua aplicação e assegure seu acesso: uma appkey.
Esta appkey está disponível na sua conta PlanningPME (se a autenticação da conta estiver activada na sua API), ou a pedido do suporte.
A appkey deve ser sempre passada nos cabeçalhos de uma chamada API, utilizando o cabeçalho dedicado "X-APPKEY".
GET /a sua_marca/api/config HTTP/1.1 Host: api.planningpme.com X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac
Para aceder à sua documentação interactiva, utilize a appkey como parâmetro de endereço, como no exemplo abaixo.
https://api.planningpme.com/a sua_marca/doc/index?appkey=e991573da5ffd4sab9b1e26bc6b64aac
2/ Ficha de utilizador e imitação
A maioria dos pedidos de API deve também apresentar um token de autorização, a fim de determinar o perfil do utilizador que acede aos dados e respeitar as autorizações de utilizador e de grupo definidas na aplicação.
Este token é obtido previamente quando um utilizador é autenticado no endereço /token e permanece válido durante 8 horas.
Os dados enviados para este endereço diferem consoante o modo de autenticação escolhido para a aplicação.
a) Autenticação tradicional
Se estiver activada, a autenticação tradicional é executada colocando o nome de utilizador e a palavra-passe.
POST /a sua_marca/token HTTP/1.1 Host: api.planningpme.com X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac Content-Type: application/x-www-form-urlencoded grant_type=password&username=o seu_nome_de_utilizador&password=a sua_password
b) Autenticação da conta
Se activada, a autenticação da conta é conseguida postando um token de conta de serviço, previamente obtido na aplicação de conta PlanningPME.

Para cada utilizador aqui listado, pode copiar o token da conta de serviço para a área de transferência.
Agora, obtenha um token de autorização da sua API, postando o token de conta copiado (asserção).
POST /a sua_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) Autenticação de cliente OAuth
Para abrir sua API a um parceiro ou a uma aplicação de terceiros, é aconselhável criar um cliente OAuth e configurar seus tokens de autenticação.
O administrador pode gerir o acesso OAuth por API, ou fazê-lo a partir do ecrã "Ferramentas > Opções > OAuth".
Uma vez que tenha os seus IDs e token de cliente OAuth, o seu terceiro poderá autenticar-se junto da API e obter um token de autorização da seguinte forma.
POST /a sua_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=token_de_cliente
d) Utilização do token de autorização
Em caso de autenticação bem sucedida, o organismo de resposta conterá um elemento JSON como se segue.
{
"access_token": "KTuZYDLG2qjUMqMVXDuiP9giFbqDXstESvpUWzBFLpkfdlMiB3PD5s2K7En-3o39u56hpr_DlyjEc_...3Is0gcH",
"token_type": "bearer",
"expires_in": 86399,
"username": "o seu_nome_de_utilizador"
}
A propriedade "access_token" contém o token de autorização da API.
Além disso, tal como indicado pela propriedade "token_type", este token é do tipo "bearer". Os pedidos que requerem autorização devem, portanto, apresentar o cabeçalho "Authorization" com o valor "Bearer", como no exemplo abaixo.
POST /a sua_marca/api/customer HTTP/1.1 Host: api.planningpme.com X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac Authorization: Bearer KTuZYDLG2qjUMqMVXDuiP9giFbqDXstESvpUWzBFLpkfdlMiB3PD5s2K7En-3o39u56hpr_DlyjEc_...3Is0gcH
Utilização de API
1/ Considerações sobre dados comuns
a) Modelos
Os modelos de dados PlanningPME podem ser facilmente descobertos usando a documentação interativa do seu API.
b) Formato da data
O formato de data utilizado pelo API e esperado em cada pedido JSON é formatoISO 8601. Ex:
2018-01-25T18:05:00Z
c) Listas de ordenação
Os métodos GET utilizam frequentemente um parâmetro "sortInfo" para definir a ordem de ordenação da lista completa/paginada devolvida.
Esta informação é composta com o nome de um bem directamente seguido por um sinal + ou -.
Por exemplo, utilizar "label+" para ordenar por ordem ascendente da propriedade "label".
É também possível combinar várias ordens anexando-as.
Por exemplo, utilizar "notValid-label+" para ordenar pela propriedade "notValid" descendente e depois pela propriedade "label" ascendente.
Esteja ciente de que as etiquetas de propriedade são sensíveis a maiúsculas e minúsculas.
d) Enumerações constantes
A lista completa dos enums em uso com a sua versão API é obtida chamando o método "/api/config". Esta lista não tem direito a alteração, excepto em caso de adição futura.
GET /a sua_marca/api/config HTTP/1.1 Host: api.planningpme.com X-APPKEY: e991573da5ffd4sab9b1e26bc6b64aac
Abaixo está a lista das constantes de enumeração. - 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) Linguagem de resposta
A língua utilizada nos textos de resposta, tais como mensagens de erro, pode ser especificada com o cabeçalho "Accept-Language".
Aceitar-Língua: pt
As línguas disponíveis no PlanningPME API e no PlanningPME WebAccess são: alemão (de), inglês (en), dinamarquês (da), espanhol (es), finlandês (fi), francês (fr), italiano (it), japonês (ja), neerlandês (nl), norueguês (no), polaco (pl), português (pt), russo (ru), sueco (sv).
2/ Exemplos de chamadas API
Nos exemplos abaixo, a chave de aplicação utilizada é "your_key" e o token de autorização "your_token". Por favor, substitua-os pelos seus próprios valores.
/api/task
→ Obtenha uma lista completa ou paginada de tarefas com o método GET "/api/task".
GET /a sua_marca/api/task?pageIndex=1&pageSize=20&sortInfo=label+ HTTP/1.1 Host: api.planningpme.com X-APPKEY: a sua_chave Authorization: Bearer seu_token
Retorna um conjunto de tarefas contendo a segunda página de 20 tarefas ordenadas por etiqueta descendente.
{
"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"
}
}
]
}
→ Obtenha uma tarefa detalhada com o método GET "/api/task/{id}".
GET /a sua_marca/api/task/756 HTTP/1.1 Host: api.planningpme.com X-APPKEY: votre_clé Authorization: Bearer seu_token
Retorna uma representação detalhada do objecto da tarefa com 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
→ Recuperar a lista dos clientes OAuth com o método GET "/api/oauth/client".
GET /a sua_marca/api/oauth/client HTTP/1.1 Host: api.planningpme.com X-APPKEY: a sua_chave Authorization: Bearer seu_token
{
"totalItems": 2,
"items": [
{
"id": "2bc87bded6bf4de7babe8ea5a9452735",
"name": "backoffice"
},
{
"id": "1601c39ed33a4c4084750356a7f8d7a5",
"name": "apptest2"
}
]
}
→ Criar um novo cliente OAuth com o método POST "/api/oauth/client".
POST /a sua_marca/api/oauth/client HTTP/1.1
Host: api.planningpme.com
X-APPKEY: votre_clé
Authorization: Bearer seu_token
{
"name": "apptest3"
}
Retorna o cliente criado e seu identificador.
{
"id": "22f37990d2304af3a9e20dc4b05efe26",
"name": "apptest3"
}
→ Criar um novo token OAuth para um cliente dado (aqui "apptest3") e um usuário dado (aqui o usuário cuja chave é 99), com o método POST "/api/oauth/token".
POST /a sua_marca/api/oauth/token HTTP/1.1
Host: api.planningpme.com
X-APPKEY: votre_clé
Authorization: Bearer seu_token
{
"clientId": "22f37990d2304af3a9e20dc4b05efe26",
"user": {
"key": 99
}
}
Retorna o token criado, sua data de expiração e a afirmação relacionada.
Atenção, a afirmação completa (propriedade "jwt") não poderá mais ser recuperada. Portanto, é aconselhável guardá-la em um local seguro assim que for criada.
{
"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"
}
→ Recuperar a lista dos tokens relacionados a um cliente OAuth com o método GET "/api/oauth/token?clientID={id}".
GET /a sua_marca/api/oauth/token?clientId=2bc87bded6bf4de7babe8ea5a9212735 HTTP/1.1 Host: api.planningpme.com X-APPKEY: a sua_chave Authorization: Bearer seu_token
{
"totalItems": 1,
"items": [
{
"id": "63d134cf760940e7af7acf16e4890835",
"userKey": 99,
"expirationDate": "2027-05-14T13:11:49.8116664Z",
"resume": "eyJhbGciOiJodHR...wtO_PkdOFllvyNk",
"invalid": false
}
]
}