Skip to content

Exchange a connect code for store credentials

POST
/v1/connect/token
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.

Media typeapplication/json
object
code
required
string
<= 256 characters
code_verifier
string
<= 128 characters
kind

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.

string
Allowed values: member_link
redirect_uri
string
<= 2048 characters

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"
}

What the store is given: its connection, or a member’s link

Media typeapplication/json
Any of:
object
connectionId
required
string
environment
required
string
integrationKey
required
object
id
required
string
key
required

The integration key itself. Shown in this response only.

string
label
required
string
memberKey
required

The member who approved the connection, linked to the store: the member key for the user who connected it.

object
key
required

The member key (mk_live_…, or mk_test_… in a sandbox). Shown in this response only.

string
memberEmail
required
string | null
memberId
required
string
memberName
required
string | null
publishableKey
required
object
allowedOrigins
required
Array<string>
id
required
string
key
required

Shown in this response only.

string
reachable
required

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.

boolean
tenantId
required
string
tenantName
required

The workspace’s name. A sandbox is named after its live workspace.

string
tenantSlug
required

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.

string
webhook
required
object
id
required
string
secret
required

The endpoint’s signing secret. Shown in this response only.

string
url
required
string

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",
"memberEmail": "[email protected]",
"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"
}
}
X-Request-Id
required
string

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

Media typeapplication/json
object
error
required
string

Examples

Exampleinvalid_grant

invalid_grant

{
"error": "invalid_grant"
}
X-Request-Id
required
string

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

Media typeapplication/json
object
error
required
string

Examples

Exampleunauthorized

unauthorized

{
"error": "unauthorized"
}
X-Request-Id
required
string

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

Media typeapplication/json
object
error
required
string
limit

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.

string
max

How many the plan allows. Always sent with plan_limit_reached.

number
plan

The plan whose limit it is. Always sent with plan_limit_reached.

string

Examples

plan_limit_reached

{
"error": "plan_limit_reached",
"limit": "templates",
"max": 0,
"plan": "free"
}
X-Request-Id
required
string

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

Media typeapplication/json
object
bytes
number
error
required
string
maxBytes

Always sent with payload_too_large.

number

Examples

Examplepayload_too_large

payload_too_large

{
"error": "payload_too_large",
"maxBytes": 0
}
X-Request-Id
required
string

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

Media typeapplication/json
object
error
required
string

Examples

Examplerate_limited

rate_limited

{
"error": "rate_limited"
}
X-Request-Id
required
string

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
error
required
string

Examples

Exampledb_error

db_error

{
"error": "db_error"
}
X-Request-Id
required
string

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].

Status · Terms of service · Privacy policy · Subprocessors