Queek docs
Merchant endpoint reference

Apps

PUT
/app/setup

Requires scope merchant-app_setup-update.

Stores the merchant-visible setup values for the calling installation (status plus the items sheet): the app calls this once its installation key is active. Full-body PUT — send the whole sheet every time.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Idempotency-Key?string

Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Store the calling installation's merchant-visible setup values (PUT app/setup). Call it once the installation's key is active.

Full-body PUT — send status plus the whole items sheet every time, so a retry replays instead of merging. Length limits apply per field; values that look like URLs must be https (a token-bearing http URL would train the merchant to paste secrets into cleartext).

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PUT "https://example.com/app/setup" \  -H "X-Client-Key: {{merchantKey}}" \  -H "Content-Type: application/json" \  -d '{    "status": "incomplete",    "items": [      {        "key": "webhook_url",        "label": "Chowdeck webhook URL",        "value": "https://apps.usequeek.com/chowdeck/hooks/1095",        "sensitive": false,        "copyable": true,        "instructions": "Paste this into Chowdeck Vendor Portal → Settings → Webhooks."      }    ]  }'
{  "status": "success",  "message": "Setup notice saved.",  "data": {    "setup": {      "status": "incomplete",      "items": [        {          "key": "webhook_url",          "label": "Chowdeck webhook URL",          "value": "https://apps.usequeek.com/chowdeck/hooks/1095",          "sensitive": false,          "copyable": true,          "instructions": "Paste this into Chowdeck Vendor Portal → Settings → Webhooks."        }      ],      "updated_at": "2026-09-24T12:00:00+01:00"    }  }}
POST
/app/alerts

Requires scope merchant-app_alerts-create.

Pages the merchant through the bell (in-app only) for the calling installation: severity, title, message and an optional dedupe key that collapses repeats. Rate-limited per installation with 429 + Retry-After past the caps.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Idempotency-Key?string

Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Send an in-app notice to the installing merchant from the calling installation (POST app/alerts). The installation comes from the calling key — the body carries no target, so one installation can never alert on another installation's behalf.

Titles and messages are bell content by design: plain text, length-capped like the manifest listing fields, rendered escaped on every surface. The optional dedupe_key lets the app collapse repeats of one problem (one failing import batch, one expired credential) inside the TTL.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/app/alerts" \  -H "X-Client-Key: {{merchantKey}}" \  -H "Content-Type: application/json" \  -d '{    "severity": "warning",    "title": "Chowdeck menu out of sync",    "message": "Two items on Chowdeck no longer match a product in your store. Open the app to relink them.",    "dedupe_key": "menu-sync-1095"  }'
{  "status": "success",  "message": "Alert sent.",  "data": {    "type": "app_alert",    "severity": "warning",    "deduped": false,    "notification_id": "019a3c51-07a2-7d3e-9a41-5b8c2f0e6d17"  }}
PUT
/app/requirements

Requires scope merchant-app-requirements-write.

Replaces the calling installation product requirements map: which products require line properties under the installation namespace and which exact claim key each requires. Products are addressed by p_id, scoped to the calling installation vendor.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Idempotency-Key?string

Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

The requirements sheet for the calling installation (PUT app/requirements): the app replaces its own {product → required line-property prefix} map in one call.

Full-body PUT — send the whole sheet every time, so a retry replays instead of merging and removals are explicit. Products are addressed by p_id (never UUID) and must belong to the calling installation's store. Each prefix must live under the installation's own app.{slug}. namespace.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PUT "https://example.com/app/requirements" \  -H "X-Client-Key: {{merchantKey}}" \  -H "Content-Type: application/json" \  -d '{    "items": [      {        "product_p_id": 20418,        "prefix": "app.booking."      }    ]  }'
{  "status": "success",  "message": "Requirements sheet saved.",  "data": {    "requirements": [      {        "product_p_id": 20418,        "prefix": "app.booking."      }    ]  }}
GET
/collected-definitions

Requires scope merchant-collected-definitions-manage.

Lists the collected definitions owned by the calling installation: the form types it created, ordered by type like the dashboard. Another installation’s types and merchant-held types never appear.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Query Parameters

limit?|
Range1 <= value <= 100
starting_after?string|null

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/collected-definitions?limit=2" \  -H "X-Client-Key: {{merchantKey}}"
{  "data": [    {      "p_id": 74,      "type": "app_forms_12_catering_enquiry",      "name": "Catering enquiry",      "description": "Enquiries from the catering form.",      "display_field": "name",      "storefront_visible": false,      "has_pages": false,      "data_class": "collected",      "entry_cap_override": null,      "retention_days": null,      "fields": [        {          "key": "name",          "name": "Name",          "type": "single_line_text",          "required": true,          "validations": []        },        {          "key": "event_date",          "name": "Event date",          "type": "date",          "required": true,          "validations": []        },        {          "key": "guests",          "name": "Guests",          "type": "integer",          "required": true,          "validations": []        }      ],      "created_at": "2026-09-15T09:00:00.000000Z",      "updated_at": "2026-09-15T09:00:00.000000Z"    }  ],  "has_more": true,  "next_cursor": "eyJpZCI6NzQsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0"}
POST
/collected-definitions

Requires scope merchant-collected-definitions-manage.

Creates a collected definition owned by the calling installation. The type must carry the installation’s own app_{slug}_{installation} prefix — anything else is refused with a 403. The data class is always collected and ownership is always the calling installation; neither is sent in the body.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Idempotency-Key?string

Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Manage the calling installation's form types (GET + POST collected-definitions, PATCH collected-definitions/{definition}).

One request shape serves all three verbs, with the same field-type, reserved-name, display and budget rules the dashboard enforces — every surface accepts the same definitions. Installation types carry the app_ prefix and declare it here. The data class is always collected and every definition belongs to the calling installation; neither is sent in the body.

Definitions are addressed by p_id within the installation's store. Types owned by another installation are refused with a 403.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/collected-definitions" \  -H "X-Client-Key: {{merchantKey}}" \  -H "Content-Type: application/json" \  -d '{    "type": "app_forms_12_catering_enquiry",    "name": "Catering enquiry",    "description": "Enquiries from the catering form.",    "display_field": "name",    "fields": [      {        "key": "name",        "name": "Name",        "type": "single_line_text",        "required": true      },      {        "key": "event_date",        "name": "Event date",        "type": "date",        "required": true      },      {        "key": "guests",        "name": "Guests",        "type": "integer",        "required": true      }    ]  }'
{  "status": "success",  "message": "Collected definition created",  "data": {    "p_id": 74,    "type": "app_forms_12_catering_enquiry",    "name": "Catering enquiry",    "description": "Enquiries from the catering form.",    "display_field": "name",    "storefront_visible": false,    "has_pages": false,    "data_class": "collected",    "entry_cap_override": null,    "retention_days": null,    "fields": [      {        "key": "name",        "name": "Name",        "type": "single_line_text",        "required": true,        "validations": []      },      {        "key": "event_date",        "name": "Event date",        "type": "date",        "required": true,        "validations": []      },      {        "key": "guests",        "name": "Guests",        "type": "integer",        "required": true,        "validations": []      }    ],    "created_at": "2026-09-15T09:00:00.000000Z",    "updated_at": "2026-09-15T09:00:00.000000Z"  }}
PATCH
/collected-definitions/{definition}

Requires scope merchant-collected-definitions-manage.

Updates one of the calling installation’s collected definitions, addressed by p_id. The type is immutable; a type another installation or the merchant holds 403s.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Path Parameters

definition*string

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Idempotency-Key?string

Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Manage the calling installation's form types (GET + POST collected-definitions, PATCH collected-definitions/{definition}).

One request shape serves all three verbs, with the same field-type, reserved-name, display and budget rules the dashboard enforces — every surface accepts the same definitions. Installation types carry the app_ prefix and declare it here. The data class is always collected and every definition belongs to the calling installation; neither is sent in the body.

Definitions are addressed by p_id within the installation's store. Types owned by another installation are refused with a 403.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PATCH "https://example.com/collected-definitions/74" \  -H "X-Client-Key: {{merchantKey}}" \  -H "Content-Type: application/json" \  -d '{    "description": "Enquiries from the catering form on adeyemifoods.com."  }'
{  "status": "success",  "message": "Collected definition updated",  "data": {    "p_id": 74,    "type": "app_forms_12_catering_enquiry",    "name": "Catering enquiry",    "description": "Enquiries from the catering form on adeyemifoods.com.",    "display_field": "name",    "storefront_visible": false,    "has_pages": false,    "data_class": "collected",    "entry_cap_override": null,    "retention_days": null,    "fields": [      {        "key": "name",        "name": "Name",        "type": "single_line_text",        "required": true,        "validations": []      },      {        "key": "event_date",        "name": "Event date",        "type": "date",        "required": true,        "validations": []      },      {        "key": "guests",        "name": "Guests",        "type": "integer",        "required": true,        "validations": []      }    ],    "created_at": "2026-09-15T09:00:00.000000Z",    "updated_at": "2026-09-24T15:40:00.000000Z"  }}
POST
/records

Requires scope merchant-collected-records-submit.

Submits one record under one of the calling installation’s collected types. Values run the same field validation entries use; every record is filed with source app. Rate-limited per installation with 429 + Retry-After past the caps, on top of the per-definition storage cap.

Authorization

merchantKey
X-Client-Key<token>

The store's private API key (sk_live_…, sk_test_… on a dev store) from Dashboard → Settings → API keys. It is bound to one store and carries the scopes the merchant granted; each operation names the scope it needs. Server-side only — never ship it to a browser or an app bundle.

In: header

Header Parameters

X-Client-Key*string

A private API key (sk_live_…, sk_test_… on a dev store) minted under Dashboard → Settings → API keys. The key is bound to ONE store, so no vendor header or vendor_id is sent; its scopes decide which operations it may call. pk_ public keys never reach this API. Keep it on your server.

X-Request-Id?string

Your own correlation id (8–128 chars, ^[A-Za-z0-9_.:-]+$). Echoed back on the response and on every log line of the request; one is generated when you omit it.

Idempotency-Key?string

Retry-safe write key. The same key with the same body replays the stored response for 24h with Idempotent-Replayed: true; with a different body it is 409 idempotency_key_reuse; while the first call is still running it is 409 idempotency_key_in_progress.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Submit one record under one of the calling installation's collected types (POST records).

Values are validated against the type's fields — the same field rules the dashboard enforces — and the per-definition storage cap is checked before anything is written. Every record is filed under the calling installation with source app: the body carries no source, so a submission can never be misfiled under another source. Calls are rate-limited per installation, and a validation failure (422) never consumes budget.

Types owned by another installation are refused with a 403.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/records" \  -H "X-Client-Key: {{merchantKey}}" \  -H "Content-Type: application/json" \  -d '{    "definition": "app_forms_12_catering_enquiry",    "values": {      "name": "Funmilayo Ogunleye",      "event_date": "2026-11-22",      "guests": 250    }  }'
{  "status": "success",  "message": "Collected record submitted",  "data": {    "p_id": 5530,    "definition_p_id": 74,    "type": "app_forms_12_catering_enquiry",    "status": "new",    "source": "app",    "submitted_at": "2026-09-24T14:20:00.000000Z",    "values": {      "name": "Funmilayo Ogunleye",      "event_date": "2026-11-22",      "guests": 250    },    "created_at": "2026-09-24T14:20:00.000000Z",    "updated_at": "2026-09-24T14:20:00.000000Z"  }}