inmake DOCS
Docs / API / Public

Public

Storefront reads with a public token.

Endpoints a storefront calls with a public token: the store document, localized content, orders and invoices by id, slugs, forms, published web pages, promo, locale and setup. Read-only, safe to call from a browser.

POST/api/public/payments/options

The payment methods a checkout may offer (.dev/plans/invoice-providers.md G6). With a catalog (setup/payments.methods) - its enabled rows that serve the country, currency and total, a module row only while its module is installed, enabled and verified. Without one - the store's legacy Stripe services, unnamed. Send the chosen row's id as payment_method to process/order/make or process/payment/init. A module token is refused (403 module_token_forbidden).

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
countrystringoptionalThe order's ISO-2 country (its price origin).
currencystringoptionalISO 4217 currency of the order.
totalnumberoptionalThe order total in major units (checked against a row's min / max).
localestringoptionalThe label locale (xx_YY).

Response

object — {methods: [{id, service, method, name, kind}]} - kind (card | bank | wallet | bnpl | other) only on a module gateway's method, as its module declares it.

Sample request

{
  "country": "CZ",
  "currency": "CZK",
  "total": 1200,
  "locale": "cs_CZ"
}
POST/api/public/store

Only read operations are allowed. Safe to use on frontend.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
masklistoptionalMasks fields in response. Returns just subset of stored object.

Response

StoreEntity — Returns store setup.

Sample request

{
  "mask": [
    "name",
    "locales",
    "status"
  ]
}
POST/api/public/content

Internally uses read/list/batch operations of /store/{storeId}/data content.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
namestringoptionalCollection name where to look up. Required unless slug is provided.
slugstringoptionalStore slug locating the content instead of name. A document slug returns that document (query params ignored); a collection slug (a collection's setup/data slug or alias, resolved at request time - not a registry entry) lists the collection (id, query, limit, order_by, offset apply). For a collection with routing enabled the two-segment form {segment}/{slug} resolves that collection's document, and {segment}/{category}/{slug} a document filed under one of its categories. A REDIRECT slug has no content - it answers 404 here; read its target from /public/slug. Takes precedence over name.
slug_localestringoptionalLocale for slug resolution - rewrites the slug target into this locale. Defaults to the slug's own locale. With slug, the plain locale param is ignored.
idstring | listoptionalSpecific object ID or list of IDs. When not null, query params are ignored.
localestringoptionalContent is typically localized. Required with name (400 when missing/invalid; a single path segment such as en_US or default) - for slug requests use slug_locale instead.
queryobjectoptionalSet of conditions to filter out documents. A scalar value ({"top" - true, "category" - "soup"}) is an equality shorthand; an object ({"price" - {"<=" - 100}}) or a list of such objects applies Firestore operators.
offsetstringoptionalID of last document.
limitintegeroptionalMaximum number of documents per page.
order_byobjectoptionalField name and direction - [asc, desc]. When omitted, a collection with manual ordering enabled (setup/data reorder + order) is returned in that manual order (offset/limit paging applies to the ordered list); an explicit order_by always wins.
masklistoptionalMasks fields in response. Returns just subset of stored object.

Response

object — Returns object or list of objects for given content.

Sample request

{
  "name": "products",
  "locale": "en_US",
  "limit": 12
}

Lists the products collection in en_US. Pass id (one id or a list) to read specific documents instead, or slug to resolve content by its public URL slug.

POST/api/public/order

Internally uses /read route.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
idstringrequiredInternal order ID.
masklistoptionalMasks fields in response. Returns just subset of stored object.

Response

OrderEntity — Returns order object. Some order data is restricted under identity-token.

Sample request

{
  "id": "ord_123"
}
POST/api/public/orders

List a customer's orders. Identity-token callers are hard-scoped to their own customer (the uid param is ignored); access-token callers pass the uid to list. Used by the incore credits shop.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
uidstringoptionalCustomer id to list orders for. Required for access-token callers; ignored (forced to the identity's customer) for identity-token callers.
queryobjectoptionalExtra field filters merged on top of the customer scope.
order_byobjectoptionalSort specification (field to asc/desc).
limitintegeroptionalMax number of orders to return.
offsetstringoptionalPagination cursor.
masklistoptionalMasks fields in each returned order.

Response

list — Returns a list of the customer's OrderEntity objects.

Sample request

{
  "uid": "user_123",
  "limit": 20
}

Identity-token callers omit uid - they always get their own orders.

POST/api/public/invoice

Returns invoice data. Without style returns structured JSON; with a render style returns raw HTML (Content-Type text/html, invoice number in the X-Invoice-Number header). style=email sends the invoice email instead. A MODULE-issued invoice (its doc carries provider, .dev/plans/invoice-providers.md A4.1) is answered from the provider's document, never the platform template: JSON = the doc + provider (no app_url) + label/status/paid_on, payment = the provider's; html/web/custom = a hand-off page (200, meta refresh + link to provider.url, header X-Invoice-Url, <meta name=x-invoice-url>); pdf = application/pdf (the stored copy, else fetched once through the module's invoice.pdf and stored at store/{sid}/invoices/{number}.pdf), falling back to the hand-off; neither a URL nor a PDF = 404 invoice_document_unavailable; email = the module's invoice.send when the doc's provider.delivery is provider (501 invoice_send_unsupported), else the platform mail with invoice_url. The invoice doc is read only for a store whose setup/invoice.provider_history is non-empty.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
idstringrequiredInternal order ID.
stylestringoptionalRender style - the template record id (html | pdf | web | any custom id; a store record at data/{locale}/templates/{style} overrides the bundled default of the same name); email sends the invoice email instead. Omitted returns invoice JSON. The legacy name 'template' is accepted as an alias.
numintegeroptionalIndex into the order's invoices array (an order can be invoiced multiple times). Defaults to the last (newest) invoice; without it an order with no invoice yet answers its invoice snapshot. Given and out of range = 404 invoice_not_found.

Response

Entity — Invoice JSON (no style; always carries oid - the order id, locale - the order's, issued_on - the document's issue date YYYY-MM-DD, and paid_on when paid), raw HTML (html/pdf/web) - or, for a module-issued invoice, the hand-off page or the PDF - or send status (email). An order paid by transfer whose vendor (setup/organization) carries a bank_account adds a payment block - account, iban, vs (from the invoice number unless order.payment.vs), amount, currency, due (order.payment.due or issue date + setup/invoice.due_days, default 14) and the spayd QR Platba payload; rendered templates get it flattened as payment_* plus payment_qr (inline SVG data URI) and payment_due_date.

Sample request

{
  "id": "ord_123",
  "style": "html"
}

Omit style for the invoice as JSON; html / pdf return the rendered document, email sends it.

POST/api/public/proforma

Returns an order's proforma (.dev/plans/proforma-invoices.md) - the advance document of a bank-transfer order, resolved strictly through the unguessable order id. Without style - JSON {number, status (issued | paid | cancelled), issued_on, paid_on, url (a module's public document), order, currency, total, items, customer, vendor, payment {amount, currency, iban, account, vs, due, iban_print, spayd}}. With a style - raw HTML: a store record data/{locale}/templates/proforma overrides the bundled default; a module-issued proforma with a public document and no store record answers a hand-off page to it. 404 proforma_not_found.

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID (header or body).
idstringrequiredThe order id.
stylestringoptionalRender style (html | pdf | web | a custom id). Omitted returns JSON.
localestringoptionalTemplate locale (default the store's).

Response

object — Proforma JSON, or raw HTML (header X-Invoice-Number).

Sample request

{
  "id": "aBcDeF123"
}
POST/api/public/slug

Internally uses /slug route. All slugs should reference to public content. A slug may target a single document (returns the document), a whole data collection (returns listing metadata - use /public/content with slug to fetch the documents), or a REDIRECT (the entry carries a "redirect" target instead of content - see the success description).

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
slugstringrequiredthe slug - one path segment (same restrictions as an ID), {segment}/{slug} for a document of a collection with routing enabled (setup/data collections[].route), or {segment}/{category}/{slug} for a document filed under one of its route.categories (seo.category); {segment}/{category} alone serves the category's index page when its registry holds no such document. A segment ALIAS of the collection or of a category answers a redirect to the same path with the primary segments. A collection's own slug/alias resolves to the collection listing metadata (derived from setup/data - the slug registry holds documents only). Four or more segments are a 404.
localestringoptionaloverrides locale of slug - typically in xx_XX format. Returns content for given slug but in overridden locale.
masklistoptionalMasks fields in response. Returns just subset of stored object.

Response

object — The target document, or for collection slugs the metadata {id, ref, locale, count, name, template} with count being a live document count. A redirect entry answers {id, kind - "redirect", redirect, external, temporary?} instead - "redirect" is an absolute URL or a root-absolute path on the store site, "external" tells the two apart, and the store servers send it as a 301 (a 302 when "temporary" is true). Redirects win over a stored path. A FORMER slug of a document (a renamed one, kept by the content sync) answers the same redirect shape, pointing at the document's current URL. The registry is one document per URL key with a per-locale map - a locale-neutral redirect wins, then the requested locale's redirect or page, then the same language's other locales, then the store default and every other locale (a page before a foreign redirect).

Sample request

{
  "slug": "about-us"
}

Resolves the document behind /about-us. For a routed collection use the two-segment form (recipes/tomato-soup); a collection's own slug returns its listing metadata.

POST/api/public/form/upload

Stage ONE file for a later form submission (multipart/form-data: a binary file part plus the text fields). The same gates as /public/form - the form must be active (404), the form doc's origins (401), require_source (400) and captcha (403 captcha_required / captcha_failed; the token rides as the multipart text field captcha and must be a fresh one - tokens are single-use - the ticket carries no stamp) apply. With source the key must be an image/file/files variable of the placing document's contract and the file must pass its accept list and max_size (400 "File type not accepted" / 413 "File too large"); without source the platform caps alone apply - 10 MiB per file, images / PDF / plain text / Office documents only (never SVG, HTML, scripts or archives). The object is stored PRIVATE under store/{sid}/forms/{form}/_files/ (no public URL) with a staging ticket that expires after 24 h unless a submission claims it - put the answered {upload} under key in the submission's data within that window. Callers SHOULD proxy this leg through their own server with the same anti-bot guards as the submission (drop-core-server serves it as POST /form/{locale}/{form}/upload).

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header (multipart bodies carry it as a text field otherwise).
formstringrequiredActive form id (slug).
localestringrequiredLocale of the submitting site (xx_YY or default) - selects the source document read.
keystringrequiredThe file-kind variable key the file is uploaded for. The submission must reference the ticket under the same key.
filefilerequiredThe binary file part (multipart/form-data field named file).
namestringoptionalFile name to store (defaults to the part's filename).
content_typestringoptionalMIME type to store (defaults to the part's). Must be in the platform list and the variable's accept.
sourcestringoptionalThe placing document ({collection}/{docId}) - validates key against its contract.
originstringoptionalBrowser origin relayed by a trusted proxy (consulted only when the form restricts origins).

Response

object — Returns {upload, name, size, content_type} - upload is the ticket id the submission claims as {upload} under key.

Sample request

{
  "form": "contact",
  "locale": "en_US",
  "key": "cv"
}

Multipart only - send a binary file part with these text fields. The Try-it rail cannot attach a file; use the render server's POST /form/{locale}/{form}/upload from a page.

POST/api/public/promo

Returns promo data for given id (customer).

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
idstringrequiredactual ID of promo - typically customer id.
masklistoptionalfilters response - credits | coupons | referrals

Sample request

{
  "id": "user_123",
  "mask": [
    "credits"
  ]
}
POST/api/public/locale

Returns global locale reference data for an ISO country code, read from the Realtime DB. Flat-merges the country (currency / unit / symbol / region / name) and vat (vat rate / reduced rates) nodes into one object; the merged country field carries the ISO code itself. Store-independent, but a valid store + access token is still required.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body. Required for auth even though the data is global.
codestringrequiredISO country code, e.g. "CZ" (case-insensitive).
masklistoptionalMasks fields in response. Returns just subset of merged fields (e.g. country, vat, currency, unit, symbol).

Response

object — Flat-merged locale object — country reference data plus VAT.

Sample request

{
  "code": "DE",
  "mask": [
    "country",
    "currency",
    "vat"
  ]
}
POST/api/public/setup

Read a single store setup document (store/{sid}/setup/{name}) that has opted into public visibility with public: true on the doc itself. Any other case - missing doc, doc without the flag, malformed name - answers the SAME generic 400, so the endpoint does not reveal which setup docs exist. Intended for browser-safe config a storefront client needs at runtime - e.g. the credits shop reads setup/payments (the Stripe publishable key).

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
namestringrequiredSetup document name (e.g. payments). Single path segment.
masklistoptionalMasks fields in response - returns just the listed top-level fields.

Response

object — The setup document body (optionally masked). Generic 400 for anything not explicitly public.

Sample request

{
  "name": "payments"
}
POST/api/public/module

Custom-module STOREFRONT leg (.dev/plans/custom-modules.md D9 / 5.5) - the core half of the reserved /m/{module}/** path space every store origin carries. The tenant server (drop-core-server) forwards such a hit here on the store's own serving token, which already grants public, so no token is re-granted for a module; the Studio renderer's preview bridge uses the same route. The module's web point is called through the gateway with the install's signed envelope and its non-secret config, and its answer is relayed - status, content-type, cache-control, body - so a module can serve HTML, JSON or a redirect under the store's own domain. The visitor's identity travels as the request's identity-token header or a relayed identity token in the body, resolved to identity = {customer} on the envelope; an invalid one is 401. The module's 5xx or a transport failure answers 502 module_unavailable; a module 4xx is relayed verbatim. A module that is not installed, is disabled, or does not declare routes.web answers 404. One module_web stat row per hit.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
modulestringrequiredThe installed module id (the manifest id, not the catalog key).
pathstringoptionalThe sub-path inside the module's own space, leading slash, no query or fragment. Defaults to /.
methodstringoptionalGET (default) | POST | PUT | DELETE.
queryobjectoptionalFlat query map. Repeated keys arrive as the first value.
bodyobjectoptionalThe request body for a non-GET call, max 256 KiB at the caller.
localestringoptionalThe visitor's locale (xx_YY), from the store's locale cookie at the tenant server.
identitystringoptionalA relayed identity token when the caller cannot send the identity-token header.
guardstringoptionalpassed - the caller vouches its form guard (honeypot, signed timing, rate limit) ran on this request. A path listed in the manifest's routes.guarded reaches the module ONLY with it; without it the answer is the envelope {status - 428, body - {error - guard_required}} and the module is not called (the tenant server then runs its FormGuard chain and retries, or - on a GET - answers the guard fields).

Response

object — {status, headers = {content-type, cache-control?}, body, guarded?} - the module's answer, for the caller to re-emit; guarded lists the module's guarded paths (when it has any) so the caller can guard before forwarding.

Sample request

{
  "module": "echo",
  "path": "/ping"
}
POST/api/public/service

Store-service STOREFRONT leg on the core path (.dev/plans/modules/services.md D9) - a /fn/{service}/** call that no sandbox host runs: the Studio / document-editor preview, forward-only render servers (own servers, server-web-prod) and custom front ends. The core runs NO guest code: it resolves the service doc, the published version, the declared secrets and the store's serving token (re-read from custody on every call; a store without one is provisioned once, else 409 no_serving_token) and forwards to the shared service-runner, whose answer is relayed in a 200 envelope - status, content-type / cache-control / location (default cache-control no-store), body as text - like /public/module. The relayed guard: passed, ip, origin and referer are taken only from a trusted relay - the store's serving token, master, owner / editor, or a token with an explicit path scope; from any other caller (an unscoped service token, an identity-token request) they are ignored. A route marked guarded needs a trusted guard: passed (else the envelope {status 428, body {error guard_required}} without calling the code); every envelope of a service with guarded routes lists them in guarded. Route access (.dev/plans/modules/service-access.md), decided before the code runs: a private route answers 404 (the no-route answer) unless a trusted relay calls with host other than site; a site route is judged on Sec-Fetch-Site / Origin vs the addressed host - the relayed fetch_site / origin / site_host from a trusted relay, else the caller's own request to the core - and a foreign, unlisted origin is the envelope {status 403, body {error origin_not_allowed}}; a signed-in route without a visitor identity is the envelope {status 401, body {error identity_required}}. Refusals count as refused in the route health, never as a log line. A trusted relay's envelopes list the non-public route keys in restricted (route key to level, e.g. GET /config - site). The visitor's identity (the identity-token header or a relayed identity) reaches the code's drop.api only on an identity: true (or signed-in) route. 404 service_unavailable for a plan without the services feature, an unknown / disabled / unpublished service or no matching route. The token's path scope must cover store/{sid}/services/{id}. Writes one log line (host core, or studio) + the route health, and one service_call stat row.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
servicestringrequiredThe service id (/fn/{id}/...).
pathstringoptionalThe path after /fn/{id}, leading slash, no query or fragment. Defaults to /.
methodstringoptionalGET (default) | POST | PUT | DELETE.
queryobjectoptionalFlat query map. Repeated keys arrive as the first value.
bodyobjectoptionalJSON request body, at most 256 KiB (413 body_too_large).
localestringoptionalThe visitor's locale (xx_YY).
identitystringoptionalA relayed identity token when the caller cannot send the identity-token header.
guardstringoptionalpassed - the caller's form guard ran on this request (required by a guarded route).
hoststringoptionalsite - a render server relaying a visitor's request (judged by route access); studio marks a console preview (its log lines say host studio; a trusted relay's studio call skips the site check and may run private routes); otherwise core.
fetch_sitestringoptionalThe visitor's raw Sec-Fetch-Site header, relayed by a render server (trusted relay only).
site_hoststringoptionalThe host the visitor addressed (x-forwarded-host or host), relayed by a render server (trusted relay only).

Response

object — {status, headers = {content-type?, cache-control?, location?}, body, guarded?, restricted?, error?} - the service's answer for the caller to re-emit (403 origin_not_allowed / 401 identity_required access refusals ride the envelope too).

Errors

404 service_unavailable; 409 no_serving_token; 401 invalid identity; 413 body_too_large.

Sample request

{
  "service": "echo",
  "path": "/ping"
}
POST/api/public/service/kv

A store service's durable key-value state (.dev/plans/modules/services.md D12, services/{id}/state/{key}) - the binding the service hosts use on the serving token; the HOST names the service, never the guest code (drop.api cannot reach /api/public/service*). Keys 1-64 of A-Z a-z 0-9 _ - (no leading _); a value is at most 64 KiB of JSON (413 value_too_large); set with a null / absent value deletes the key. set is checked as a WRITE against the token's path scope (every other /public call is a read) and needs the tier feature services (403 tier_required). 404 service_unavailable for an unknown service. Only the store's serving token (the service hosts) and master reach it - any other token, and any identity-token request, is 403 serving_token_required.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
servicestringrequiredThe service id.
opstringrequiredget | set.
keystringrequiredThe key.
valueobjectoptionalThe JSON value to store (set).

Response

object — get -> {value} (null when absent); set -> {ok: true}

Sample request

{
  "service": "echo",
  "op": "get",
  "key": "counter"
}
POST/api/public/shipping/options

The delivery methods a cart may choose (plans/carriers 3.6) - setup/delivery priced for the cart - enabled, shipping to country (a method without countries ships to the sender's country only), free_from applied on total, the per-origin price when set, minus the methods of a module:{id} carrier that is not selectable (disabled / unverified / uninstalled). The storefront server's POST /delivery/:locale and the Studio bridge return this list.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
countrystringoptionalDestination ISO-2 country.
totalnumberoptionalThe cart total (the free_from threshold).
originstringoptionalThe price origin (country).
localestringoptionalThe label locale (xx_YY).

Response

object — {methods: [{id, carrier, service, kind, name, price, currency, vat, free, cod, point_types, widget}]}

Sample request

{
  "country": "CZ",
  "total": 1200,
  "locale": "cs_CZ"
}
POST/api/public/shipping/points

Pickup points for the checkout (plans/carriers 3.4) - only for a carrier some enabled point / box method of the store names (else 404 carrier_not_offered); cached per instance ~10 min per (store, carrier, query).

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
carrierstringrequiredThe carrier tag of a delivery method.
countrystringoptionalISO-2 country.
typestringoptionalThe carrier point type (e.g. AlzaBox).
qstringoptionalFree-text search (name, town, street, zip).
localestringoptionalThe label locale (xx_YY).

Response

object — {points: [...]}

Sample request

{
  "carrier": "mock",
  "country": "CZ"
}
POST/api/public/shipping/track

The customer tracking view (plans/carriers 3.6) - order + tracking (the tracking number is the proof; a wrong one is 404). Answers {order, status, carrier, tracking, tracking_url, last, town, history - [{code, status, text, at}]}; no PII beyond the destination town.

Parameters

NameTypeRequiredDescription
storestringoptionalPreferred in header, but store ID can be also used in request body.
orderstringrequiredThe order id.
trackingstringrequiredThe shipment's tracking number.

Response

object — {order, status, carrier, tracking, tracking_url, last, town, history}

Sample request

{
  "order": "Hk8yR64vJf2bz33yc44B",
  "tracking": "MOCK1234"
}