Exchange a connect code for store credentials
const url = 'https://api.pixonaut.app/v1/connect/token';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"code":"c_4f8a1d2e9b7c4a6f8e3d5b1a","code_verifier":"dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk","redirect_uri":"https://shop.acme.example/wp-admin/admin.php?page=pixonaut-connect"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.pixonaut.app/v1/connect/token \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "code": "c_4f8a1d2e9b7c4a6f8e3d5b1a", "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "redirect_uri": "https://shop.acme.example/wp-admin/admin.php?page=pixonaut-connect" }'Operation ID: connectedStore.exchangeCode
Called by the store’s server with the code the studio sent its merchant back with, the PKCE verifier it made the challenge from, and the same redirect_uri. Answers, once, an integration key, a publishable key bound to the store’s origin, a webhook endpoint registered at the store with its signing secret, and the member key of the member who approved. A code works once, for a minute: any attempt uses it, and every refusal is invalid_grant, after which the store connects again. Connecting a site that is already connected replaces its connection, revoking what it was given before. With kind: "member_link" and the store’s integration key as the bearer, exchanges a member link’s code for the approving member’s member key instead; a code approved for another store or workspace is invalid_grant.
Authorizations
Section titled “Authorizations”- integrationKey
- None
Request Bodyrequired
Section titled “Request Bodyrequired”object
Exchanges a member link’s code, sent with the store’s integration key as the bearer, for the approving member’s member key. Left out, the code connects the store, and no bearer is read.
Examples
Connecting a store: 3. Exchange the code
{ "code": "c_4f8a1d2e9b7c4a6f8e3d5b1a", "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "redirect_uri": "https://shop.acme.example/wp-admin/admin.php?page=pixonaut-connect"}Example
{ "code": "c_4f8a1d2e9b7c4a6f8e3d5b1a", "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "redirect_uri": "https://shop.acme.example/wp-admin/admin.php?page=pixonaut-connect"}Responses
Section titled “Responses”What the store is given: its connection, or a member’s link
object
object
The integration key itself. Shown in this response only.
The member who approved the connection, linked to the store: the member key for the user who connected it.
object
The member key (mk_live_…, or mk_test_… in a sandbox). Shown in this response only.
object
Shown in this response only.
Whether the store’s webhook address answered when it was last checked: when the store was approved, or when the address was last sent to PATCH /v1/webhooks/{id}. A sandbox store whose address did not (a local machine, a private address) is connected anyway, but no delivery is enqueued for it, and it reads its events by pulling them with GET /v1/events. Always true for a live store, which is refused an address that does not answer.
The workspace’s name. A sandbox is named after its live workspace.
The workspace’s slug, unique across Pixonaut and never changed: studio pages of the workspace are under /w/<tenantSlug>/, so a link to one of its designs is /w/<tenantSlug>/designs/<id>. A sandbox has its own.
object
The endpoint’s signing secret. Shown in this response only.
object
The member key (mk_live_…, or mk_test_… in a sandbox). Shown in this response only.
Examples
Connecting a store: 3. Exchange the code
{ "connectionId": "sc_0b1c2d3e-4f50-4a6b-8c7d-000000000004", "environment": "live", "integrationKey": { "id": "0b1c2d3e-4f50-4a6b-8c7d-000000000005", "key": "ik_live_0123456789abcdef01234567", "label": "WooCommerce · Acme Shop (shop.acme.example)" }, "memberKey": { "key": "mk_live_fedcba9876543210fedcba98", "memberId": "usr_0b1c2d3e4f504a6b8c7d0008", "memberName": "Alex Merchant" }, "publishableKey": { "allowedOrigins": [ "https://shop.acme.example" ], "id": "0b1c2d3e-4f50-4a6b-8c7d-000000000006", "key": "pk_live_89abcdef0123456789abcdef" }, "reachable": true, "tenantId": "0b1c2d3e-4f50-4a6b-8c7d-000000000003", "tenantName": "Acme", "tenantSlug": "acme", "webhook": { "id": "0b1c2d3e-4f50-4a6b-8c7d-000000000007", "secret": "whsec_0123456789abcdef0123456789abcdef", "url": "https://shop.acme.example/wp-json/pixonaut/v1/webhook" }}Example
{ "connectionId": "sc_0b1c2d3e-4f50-4a6b-8c7d-000000000004", "environment": "live", "integrationKey": { "id": "0b1c2d3e-4f50-4a6b-8c7d-000000000005", "key": "ik_live_0123456789abcdef01234567", "label": "WooCommerce · Acme Shop (shop.acme.example)" }, "memberKey": { "key": "mk_live_fedcba9876543210fedcba98", "memberId": "usr_0b1c2d3e4f504a6b8c7d0008", "memberName": "Alex Merchant" }, "publishableKey": { "allowedOrigins": [ "https://shop.acme.example" ], "id": "0b1c2d3e-4f50-4a6b-8c7d-000000000006", "key": "pk_live_89abcdef0123456789abcdef" }, "reachable": true, "tenantId": "0b1c2d3e-4f50-4a6b-8c7d-000000000003", "tenantName": "Acme", "tenantSlug": "acme", "webhook": { "id": "0b1c2d3e-4f50-4a6b-8c7d-000000000007", "secret": "whsec_0123456789abcdef0123456789abcdef", "url": "https://shop.acme.example/wp-json/pixonaut/v1/webhook" }}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Refused: invalid_grant
object
Examples
invalid_grant
{ "error": "invalid_grant"}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Refused: unauthorized
object
Examples
unauthorized
{ "error": "unauthorized"}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Refused: plan_limit_reached, workspace_suspended
object
The limit the tenant is at: templates, connectedStores, apiKeys, shareLinks, customDomains, printsMadePerMonth (prints made without an order this month), members, orders (this month’s orders, which getting a print’s files without an order counts as), or a sandbox’s own caps: sandboxPrintsPerDay, sandboxPrintsPerMonth, sandboxOrdersPerMonth. A sandbox shares every other limit with its live workspace. Always sent with plan_limit_reached.
How many the plan allows. Always sent with plan_limit_reached.
The plan whose limit it is. Always sent with plan_limit_reached.
Examples
plan_limit_reached
{ "error": "plan_limit_reached", "limit": "templates", "max": 0, "plan": "free"}workspace_suspended
{ "error": "workspace_suspended"}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Refused: payload_too_large
object
Always sent with payload_too_large.
Examples
payload_too_large
{ "error": "payload_too_large", "maxBytes": 0}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Refused: rate_limited
object
Examples
rate_limited
{ "error": "rate_limited"}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Refused: db_error. A request that failed unexpectedly answers as text instead.
object
Examples
db_error
{ "error": "db_error"}Headers
Section titled “Headers”Every response names the request it answers in X-Request-Id: the id the request was sent with in that header, when it is well formed, else one the API gave it. Quote it when reporting a refusal or a failure: the API’s log lines for that request carry it.
Questions? Write to [email protected].