{"items":[{"type":"link","label":"Authentication","link":"/apis/auth","routeSlug":"/apis/auth","content":{"contentType":"overview","meta":{"name":"Authentication"},"children":[{"nodeType":"container","panels":[{"title":"Download OpenAPI description","titleTranslationKey":"download.description.title","children":[{"kind":"download","label":"auth.json","url":"/_bundle/apis/auth.json?download"},{"kind":"download","label":"auth.yaml","url":"/_bundle/apis/auth.yaml?download"}]},{"title":"Overview","titleTranslationKey":"info.title","children":[{"kind":"email","title":"E-mail","titleTranslationKey":"info.contact.name","email":"apisupport@quiqup.com","label":"apisupport@quiqup.com","withCopyButton":true,"copyContent":"apisupport@quiqup.com"},{"kind":"externallink","title":"License","titleTranslationKey":"info.license","label":"Proprietary","url":"https://quiqup.com/terms"}]},{"title":"Languages","titleTranslationKey":"languages.title","children":[{"kind":"languages","options":[{"key":"curl","title":"curl","lang":"curl"},{"key":"javascript","title":"JavaScript","lang":"JavaScript"},{"key":"node","title":"Node.js","lang":"Node.js"},{"key":"python","title":"Python","lang":"Python"},{"key":"java","title":"Java","lang":"Java"},{"key":"csharp","title":"C#","lang":"C#"},{"key":"php","title":"PHP","lang":"PHP"},{"key":"go","title":"Go","lang":"Go"},{"key":"ruby","title":"Ruby","lang":"Ruby"},{"key":"r","title":"R","lang":"R"},{"key":"payload","title":"Payload","lang":"Payload"}]}]},{"title":"Servers","titleTranslationKey":"servers.title","children":[{"kind":"servers","servers":[{"url":"https://api.staging.quiqup.com","description":"Last-mile, staging"},{"url":"https://api-ae.quiqup.com","description":"Last-mile, production"},{"url":"https://platform-api.staging.quiqup.com","description":"Fulfilment, staging"},{"url":"https://platform-api.quiqup.com","description":"Fulfilment, production"}],"mode":"default"}]}],"children":[{"nodeType":"overview-section-wrapper","children":[{"nodeType":"header","level":1,"label":"Authentication (1.0)","showPageActions":true},{"nodeType":"overview-section-wrapper","children":[{"nodeType":"markdoc","content":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Exchange a "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_id"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" and "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_secret"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" for a Bearer access token."},"children":[]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"One credential set covers both APIs."},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" The same OAuth2 client credentials, and the same Quiqdash"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Bearer key, authenticate against the Fulfilment host and the Last-mile host. There is no separate"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"fulfilment credential to request."},"children":[]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Most integrations do not need the exchange at all. A Bearer token generated in Quiqdash under"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Organization -> API keys grants identical access with no token endpoint involved. Client credentials"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"exist for middleware and carrier platforms whose setup screens require a Client ID and Client Secret."},"children":[]}]}]}]}],"sectionId":"/apis/auth"}],"sectionId":"/apis/auth"}]}]}},{"type":"group","label":"Auth","link":"/apis/auth/auth","routeSlug":"/apis/auth/auth","items":[{"label":"Authorization token","deprecated":false,"httpVerb":"post","isAdditionalOperation":false,"isWebhook":false,"type":"link","link":"/apis/auth/auth/authorization-token","routeSlug":"/apis/auth/auth/authorization-token","metadata":{"seo":{"title":"Authorization token","description":"Every endpoint on both APIs supports OAuth 2.0. For background, seeoAuth 2.0."}},"content":{"contentType":"item","itemVariant":"httpItem","meta":{"sourceId":"authorization-token","name":"Authorization token","deprecated":false,"isWebhook":false,"pointer":"/paths/~1oauth~1token/post","hasSamples":true},"children":[{"nodeType":"container","children":[{"nodeType":"header","level":2,"label":"Authorization token","isWebhook":false,"deprecated":false,"showPageActions":true}],"panels":[]},{"nodeType":"container","children":[{"nodeType":"header","level":4,"label":"Request","labelTranslationKey":"request","deepLinkSuffix":"request"},{"nodeType":"markdoc","content":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Every endpoint on both APIs supports OAuth 2.0. For background, see"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"link","inline":true,"attributes":{"href":"https://oauth.net/2/"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"oAuth 2.0"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"To send authenticated requests:"},"children":[]}]}]},{"$$mdtype":"Node","type":"list","attributes":{"ordered":true,"marker":"."},"children":[{"$$mdtype":"Node","type":"item","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Exchange your "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_id"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" and "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_secret"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" for an access token. Client credentials, and the"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"tokens exchanged from them, differ between staging and production. They do "},"children":[]},{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"not"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" differ"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"between Fulfilment and Last-mile. A Bearer token generated in Quiqdash needs none of this:"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"generate it on the dashboard of the environment you will call. Its lifetime is the"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Expiration"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" chosen at creation, one of Never, 1 Day, 7 Days, 30 Days or 60 Days. See"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"link","inline":true,"attributes":{"href":"/docs/environments#which-credentials-cross-environments"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Which credentials cross environments"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]},{"$$mdtype":"Node","type":"item","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"The response carries an access token and a refresh token. The lifetimes are stated once, in"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"link","inline":true,"attributes":{"href":"/docs/authentication#token-lifetime"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Token lifetime"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":". Read "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"expires_in"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" from the response rather"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"than hard-coding it."},"children":[]}]}]},{"$$mdtype":"Node","type":"item","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Handle renewal. Before the access token expires, or on a 401, either send"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"grant_type=refresh_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" with the refresh token, or exchange the client id and secret again."},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"A refresh token works once, see "},"children":[]},{"$$mdtype":"Node","type":"link","inline":true,"attributes":{"href":"/docs/authentication#refreshing"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Refreshing"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]},{"$$mdtype":"Node","type":"heading","attributes":{"level":2,"id":"auth/authorization-token/request/which-host","deepLinkHash":"/auth/authorization-token#auth/authorization-token/request/which-host"},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Which host"},"children":[]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Call the token endpoint on the host you are about to use. Within one environment the token is"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"accepted on both, so a single exchange is enough for an integration that spans the two APIs."},"children":[]}]}]},{"$$mdtype":"Node","type":"heading","attributes":{"level":2,"id":"auth/authorization-token/request/aggregator-or-platform-integration","deepLinkHash":"/auth/authorization-token#auth/authorization-token/request/aggregator-or-platform-integration"},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Aggregator or platform integration?"},"children":[]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Three options:"},"children":[]}]}]},{"$$mdtype":"Node","type":"list","attributes":{"ordered":true,"marker":"."},"children":[{"$$mdtype":"Node","type":"item","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Billing identifiers."},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" Avoids Client ID and Client Secret entirely. You use your own API keys"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"and pass a billing identifier, which maps the order to a specific customer. You remain the"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"author of these orders; the client owns them. A client with several brands can only see each"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"brand in its own dashboard."},"children":[]}]}]},{"$$mdtype":"Node","type":"item","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"API keys per account."},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" The client gets its own keys and becomes both author and owner. Again,"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"a client with multiple brands has one account per brand."},"children":[]}]}]},{"$$mdtype":"Node","type":"item","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Master account keys plus billing identifiers per brand."},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" A combination of the two. The client"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"gets keys and Quiqup configures billing IDs per brand."},"children":[]}]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Billing IDs can come from the client, from the platform, or from Quiqup. How an identifier behaves"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"on an order is described in "},"children":[]},{"$$mdtype":"Node","type":"link","inline":true,"attributes":{"href":"/docs/lastmile/create-an-order#billing_identifier"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"billing_identifier"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]},{"nodeType":"item-content","variant":"body","label":"Request Body","labelTranslationKey":"body","required":true,"mediaTypes":["application/x-www-form-urlencoded","application/json"],"mediaTypeSchemas":{"application/x-www-form-urlencoded":{"schemaId":"schema_0","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials","paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token"]},"application/json":{"schemaId":"schema_1","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1json/examples/client_credentials"]}},"schemaId":"schema_0","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials","paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token"],"pointer":"/paths/~1oauth~1token/post/requestBody","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Send the parameters in the body, form-encoded or as JSON. The endpoint also reads them from the query string, but a "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_secret"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" in a URL ends up in server, proxy and browser logs, so do not send it that way."},"children":[]}]}]}]}],"panels":[{"children":[{"kind":"code-sample","source":{"kind":"code-sample","operationType":"http","method":"POST","path":"/oauth/token","servers":[{"url":"https://api.staging.quiqup.com","description":"Last-mile, staging"},{"url":"https://api-ae.quiqup.com","description":"Last-mile, production"},{"url":"https://platform-api.staging.quiqup.com","description":"Fulfilment, staging"},{"url":"https://platform-api.quiqup.com","description":"Fulfilment, production"}],"parameters":{"path":[],"query":[],"querystring":[],"header":[],"cookie":[]},"security":[],"requestBody":{"application/x-www-form-urlencoded":{"schemaId":"schema_0","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials","paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token"]},"application/json":{"schemaId":"schema_1","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1json/examples/client_credentials"]}},"responseCodes":["200","401"],"pointer":"/oauth/token","href":"auth/authorization-token","openApiOperationId":"authorization-token","summary":"Authorization token"},"isWebhook":false,"hideReplay":false,"servers":[{"url":"https://api.staging.quiqup.com","description":"Last-mile, staging"},{"url":"https://api-ae.quiqup.com","description":"Last-mile, production"},{"url":"https://platform-api.staging.quiqup.com","description":"Fulfilment, staging"},{"url":"https://platform-api.quiqup.com","description":"Fulfilment, production"}],"schemaId":"schema_0","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials","paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token"],"mediaTypes":["application/x-www-form-urlencoded","application/json"],"mediaTypeSchemas":{"application/x-www-form-urlencoded":{"schemaId":"schema_0","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials","paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token"]},"application/json":{"schemaId":"schema_1","exampleIds":["paths/~1oauth~1token/post/requestBody/content/application~1json/examples/client_credentials"]}},"examples":[{},{}]}]}]},{"nodeType":"container","children":[{"nodeType":"header","level":4,"label":"Responses","labelTranslationKey":"responses","deepLinkSuffix":"responses"},{"nodeType":"item-content","variant":"responses","responses":[{"code":"200","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"expires_in"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" is how many "},"children":[]},{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"seconds"},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" the returned "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"access_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" is valid for. After that,"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"refresh it with the "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"refresh_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":", or request this endpoint again with the client id and secret."},"children":[]}]}]},{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"strong","inline":true,"attributes":{"marker":"**"},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Check the body, not the status."},"children":[]}]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" A "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_id"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" that does not exist is rejected with"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"{\"error\": \"invalid_client\", \"error_description\": \"...\"}"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" and no "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"access_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":", and that"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"response is HTTP 200 on staging and HTTP 401 on production. A wrong secret for a real client id"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"is a 401. Branch on the presence of "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"access_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":", not on the status code."},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"A request with no "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"grant_type"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" returns 401 with "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"unsupported_grant_type"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":". A refresh token"},"children":[]},{"$$mdtype":"Node","type":"softbreak","inline":true,"attributes":{},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"that was already used, or has expired, is rejected with "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"invalid_grant"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}],"mediaType":"application/json","mediaTypes":["application/json"],"mediaTypeContent":{"application/json":{"schemaId":"schema_2","exampleIds":["paths/~1oauth~1token/post/responses/200/content/application~1json/examples/issued","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/rejected","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/invalid_grant"]}},"schemaId":"schema_2","exampleIds":["paths/~1oauth~1token/post/responses/200/content/application~1json/examples/issued","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/rejected","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/invalid_grant"]},{"code":"401","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"unsupported_grant_type"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":". The "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"grant_type"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":" was missing or not recognised."},"children":[]}]}]}],"mediaType":"application/json","mediaTypes":["application/json"],"mediaTypeContent":{"application/json":{"schemaId":"schema_3"}},"schemaId":"schema_3"}],"pointer":"/paths/~1oauth~1token/post/responses"}],"panels":[{"children":[{"kind":"response","responseCodes":[{"code":"200","schemaId":"schema_2","exampleIds":["paths/~1oauth~1token/post/responses/200/content/application~1json/examples/issued","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/rejected","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/invalid_grant"],"mediaTypes":["application/json"],"mediaTypeContent":{"application/json":{"schemaId":"schema_2","exampleIds":["paths/~1oauth~1token/post/responses/200/content/application~1json/examples/issued","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/rejected","paths/~1oauth~1token/post/responses/200/content/application~1json/examples/invalid_grant"]}}},{"code":"401","schemaId":"schema_3","mediaTypes":["application/json"],"mediaTypeContent":{"application/json":{"schemaId":"schema_3"}}}],"examples":[]}]}]},{"nodeType":"container","children":[{"nodeType":"feedback","pageSlug":"/auth/authorization-token"}],"panels":[]}]},"httpPath":"/oauth/token"}],"content":{"contentType":"group","meta":{"name":"Auth"},"children":[{"nodeType":"container","children":[{"nodeType":"header","level":2,"label":"Auth","showPageActions":true},{"nodeType":"markdoc","content":"Auth endpoints."}],"panels":[{"children":[{"kind":"group-items","title":"Operations","titleTranslationKey":"operations","items":[{"title":"/oauth/token","summary":"Authorization token","prefix":{"name":"post","color":"post"},"badges":[],"link":"/auth/authorization-token","deprecated":false}]}]}]}]}}],"store":{"schemaStore":{"schema_0":{"kind":"json-schema","data":{"type":"object","required":["grant_type"],"properties":{"grant_type":{"type":"string","default":"client_credentials","enum":["client_credentials","refresh_token"]},"client_id":{"type":"string","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Required for "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_credentials"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]},"client_secret":{"type":"string","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Required for "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_credentials"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]},"refresh_token":{"type":"string","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Required for "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"refresh_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":". Single use."},"children":[]}]}]}]}}},"id":"schema_0"},"schema_1":{"kind":"json-schema","data":{"type":"object","required":["grant_type"],"properties":{"grant_type":{"type":"string","default":"client_credentials","enum":["client_credentials","refresh_token"]},"client_id":{"type":"string","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Required for "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_credentials"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]},"client_secret":{"type":"string","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Required for "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"client_credentials"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]},"refresh_token":{"type":"string","description":[{"$$mdtype":"Node","type":"paragraph","attributes":{},"children":[{"$$mdtype":"Node","type":"inline","attributes":{},"children":[{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"Required for "},"children":[]},{"$$mdtype":"Node","type":"code","inline":true,"attributes":{"content":"refresh_token"},"children":[]},{"$$mdtype":"Node","type":"text","inline":true,"attributes":{"content":"."},"children":[]}]}]}]}}},"id":"schema_1"},"schema_2":{"kind":"json-schema","data":{"oneOf":[{"title":"Token issued","type":"object","required":["access_token"],"properties":{"access_token":{"type":"string"},"token_type":{"type":"string","default":"bearer"},"expires_in":{"type":"integer"},"refresh_token":{"type":"string"},"created_at":{"type":"integer"}}},{"title":"Credentials rejected, still HTTP 200","type":"object","required":["error"],"properties":{"error":{"type":"string"},"error_description":{"type":"string"}}}]},"id":"schema_2"},"schema_3":{"kind":"json-schema","data":{"type":"object","properties":{"error":{"type":"string"},"error_description":{"type":"string"},"created_at":{"type":"integer"}}},"id":"schema_3"}},"exampleStore":{"paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials":{"value":{"grant_type":"client_credentials","client_id":"your_client_id","client_secret":"your_client_secret"},"key":"client_credentials","summary":"client_credentials","id":"paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/client_credentials"},"paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token":{"value":{"grant_type":"refresh_token","refresh_token":"your_refresh_token"},"key":"refresh_token","summary":"refresh_token","id":"paths/~1oauth~1token/post/requestBody/content/application~1x-www-form-urlencoded/examples/refresh_token"},"paths/~1oauth~1token/post/requestBody/content/application~1json/examples/client_credentials":{"value":{"grant_type":"client_credentials","client_id":"your_client_id","client_secret":"your_client_secret"},"key":"client_credentials","summary":"client_credentials","id":"paths/~1oauth~1token/post/requestBody/content/application~1json/examples/client_credentials"},"paths/~1oauth~1token/post/responses/200/content/application~1json/examples/issued":{"value":{"access_token":"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.example.signature","token_type":"Bearer","expires_in":604800,"refresh_token":"EXAMPLEREFRESHTOKEN0123456789ABCDEF0123456789AB","created_at":1616571253},"key":"issued","summary":"Token issued, seven days","id":"paths/~1oauth~1token/post/responses/200/content/application~1json/examples/issued"},"paths/~1oauth~1token/post/responses/200/content/application~1json/examples/rejected":{"value":{"error":"invalid_client","error_description":"Client authentication failed."},"key":"rejected","summary":"Unknown client id, 200 on staging","id":"paths/~1oauth~1token/post/responses/200/content/application~1json/examples/rejected"},"paths/~1oauth~1token/post/responses/200/content/application~1json/examples/invalid_grant":{"value":{"error":"invalid_grant","error_description":"The provided authorization grant is invalid, expired or revoked."},"key":"invalid_grant","summary":"Refresh token already used or expired","id":"paths/~1oauth~1token/post/responses/200/content/application~1json/examples/invalid_grant"}},"securitySchemeStore":{},"servers":[{"url":"https://api.staging.quiqup.com","description":"Last-mile, staging"},{"url":"https://api-ae.quiqup.com","description":"Last-mile, production"},{"url":"https://platform-api.staging.quiqup.com","description":"Fulfilment, staging"},{"url":"https://platform-api.quiqup.com","description":"Fulfilment, production"}],"specType":"openapi"},"options":{"mockServer":{"off":true},"disableRouter":true,"downloadUrls":[{"url":"/_bundle/apis/auth.json?download"},{"url":"/_bundle/apis/auth.yaml?download"}],"excludeFromSearch":false,"replayFeatures":{"graphql":false},"specType":"openapi","markdocOptions":{"tags":{},"nodes":{},"components":{}},"metadata":{"title":"Authentication","description":"Exchange a `client_id` and `client_secret` for a Bearer access token.\n\n**One credential set covers both APIs.** The same OAuth2 client credentials, and the same Quiqdash\nBearer key, authenticate against the Fulfilment host and the Last-mile host. There is no separate\nfulfilment credential to request.\n\nMost integrations do not need the exchange at all. A Bearer token generated in Quiqdash under\nOrganization -> API keys grants identical access with no token endpoint involved. Client credentials\nexist for middleware and carrier platforms whose setup screens require a Client ID and Client Secret.\n"}},"baseSlug":"/apis/auth","routesMapping":{}}