Worked public samples
No X-API-Key required — and none accepted. Every route on this page is
public by design: the API ignores the key entirely, so the samples below
omit it. Signed links, tokens, or public query parameters authorize the
caller where noted; do not add an API key to a browser embed.
The endpoint list below documents every public route’s parameters; this
overlay walks the surfaces a signed-out visitor actually hits:
callback links, the community and idea boards, shared recordings and
embeds, sub-processor notices, then the survey link, the hosted consent
form, and an agentic-commerce checkout. Success envelopes are
{ data, meta } and error envelopes { error, meta }, except where a
route serves a raw protocol document or an HTML page; the four shapes
together are documented in How to read a worked
sample.
Every response carries meta.request_id. Quote the request id when you
report an out-of-window token or a misfired cancel so support can trace
the request end-to-end.
1. Look up a callback token
GET /api/v1/public/callbacks/{token} returns the callback’s arrival
state — ok: true with status set to pending, running, succeeded,
failed, or canceled. It also reports whether a cancel and a reschedule
request would still be accepted, so your confirmation page can hide an
action that would 409. The route ignores X-API-Key; the sample sends
nothing.
200
caller masks the calling number for screen readers and logs; the full
E.164 number only resolves inside your tenant-scoped callback list.
2. Check a callback’s status
GET /api/v1/public/callbacks/{token}/status answers the same envelope
without the embedded PII — use it for a barebones “still pending” check on
the confirmation page before you offer the cancel button.
200
3. Cancel the callback
POST /api/v1/public/callbacks/{token}/cancel stops the remaining retry
attempts and flips the callback to canceled. It works even after an
attempt already ran — already_canceled: true tells you a previous cancel
won, and the request is idempotent.
200
4. Reschedule the callback
POST /api/v1/public/callbacks/{token}/reschedule moves the callback to a
new scheduled_for and resets the retry ladder. Rotate scheduled_for —
send the new timestamp when you re-issue the token.
200
5. Errors
Errors follow the{ error, meta } envelope. Two failures every token
holder hits:
404 — token not found or out of window. A guessed token was never
issued or the callback window already closed. Do not retry.
404
429
Community surface + consent envelopes, worked
The community board, the idea board, the published roadmap, shared recordings and dashboard embeds, and the sub-processor subscription handshake are all reach-in surfaces for a signed-out visitor, so none of them accept a tenant API key — anX-API-Key header is simply ignored
here and the samples below omit it. Scope the community and idea calls
with ?org=<your-org-slug>; both boards are opt-in, and an unknown slug
or a disabled board collapses to the same 404 so a probe cannot tell the
two apart.
Consent envelopes stay tenant-owned: a subscription records only the
channel (
email or webhook), the endpoint, the subscriber locale, and
the double-opt-in state. Confirm and unsubscribe links are signed,
single-purpose tokens that expire after 30 days, and one click from the
notice email flips state — no session, no password.6. Browse and read community questions
GET /api/v1/public/community/questions lists published questions with
vote, answer, and view counts — ?sort=recent|top|unanswered, an optional
q full-text filter, and limit/offset pagination.
200
GET /api/v1/public/community/questions/{id} returns the question with
its published answers, and bumps the view counter — never edge-cache it.
Up-vote with POST /api/v1/public/community/questions/{id}/vote?org=acme
(an empty body is fine); the call is idempotent per visitor, so a repeat
returns voted: false with the unchanged count:
200
7. Read the idea board and up-vote
GET /api/v1/public/ideas lists feature-request ideas with their
lifecycle status (under_review, planned, in_progress, shipped,
declined) — visitors can submit and vote, but only your team moves an
idea onto the roadmap.
200
POST /api/v1/public/ideas/{id}/vote?org=acme — same
idempotent-per-visitor contract as the question vote above.
8. Read the public roadmap
GET /api/v1/public/ideas/roadmap returns the three roadmap columns —
planned, in_progress, shipped — each capped and ordered by votes
(the shipped column reads newest-first and doubles as a “what we shipped”
changelog). Pair it with the content pages under
GET /api/v1/public/pages and GET /api/v1/public/pages/{slug} when you
need the published copy that explains a column.
200
9. Resolve a shared recording or a dashboard embed
GET /api/v1/public/recordings/{token} resolves a signed recording share
link minted from the dashboard’s share action and returns the player HTML
for the recipient — never the underlying storage path. An expired or
revoked link answers 404 with the same non-disclosing page.
GET /api/v1/public/analytics/dashboards/embed?token=… is the
white-label variant for analytics: it verifies the signed grant and
returns the layout snapshot plus the minting org’s public branding theme
so the embed page renders inside your iframe.
200
no-store, and a tampered or expired grant
collapses to the same 404 without distinguishing which.
10. Subscribe to sub-processor change notices
POST /api/v1/public/subprocessor-subscriptions registers an email or a
webhook endpoint for advance notice before Devotel adds or replaces a
sub-processor. The Devotel site signs this call server-side, so a typical
integration posts through its own backend or the site form rather than
from a browser. The request is idempotent per endpoint: re-subscribing
the same address returns the same subscription id and re-opens the
double-opt-in.
201
11. Confirm and unsubscribe from the notice email
Every notice email carries both links. The token template isv1.<payload>.<signature> — a signed, single-purpose credential bound to
one subscription, valid 30 days.
GET /api/v1/public/subprocessor-subscriptions/confirm?token=… completes
the double opt-in and flips the subscription to confirmed:
GET /api/v1/public/subprocessor-subscriptions/unsubscribe?token=… is
the one-click footer link — it flips any state to unsubscribed and is
safe to re-hit. Both endpoints answer an HTML page for the human who
clicked; a missing, malformed, or expired token renders “link not valid”
with a prompt to subscribe again, and re-subscribing from the
sub-processor page mints a fresh pair of tokens on the same subscription
id.
Survey links, consent forms, and agentic commerce, worked
Survey invitation links, hosted consent landing pages, and the agentic-commerce (ACP) checkout are the three public surfaces your recipients and shopping agents drive straight from a browser or an agent runtime. Like the boards above, all three ignoreX-API-Key; the token
or the storefront id in the path is the credential.
12. Open a survey invitation link
GET /api/v1/public/surveys/{token}text/html), not JSON: a
self-contained page with a 0-10 score row and an optional comment box, or
a thank-you page when the recipient already answered. The JSON block on
the generated entry above is a schema placeholder; browsers and iframe
embeds render the page below.
200
404 HTML page —
This feedback link has expired or is invalid. — identical for tokens
that never existed, so a probe cannot enumerate survey ids. See How to
read a worked sample for the error envelope
used by the JSON surfaces below.
404
13. Submit a survey response (HTML vs JSON)
POST /api/v1/public/surveys/{token}/submitAccept
header: JSON clients get the { data, meta } envelope, form posts get a
thank-you page.
200
Accept header (or send Accept: text/html) from a form post
and the same call answers the thank-you page a human sees after clicking
submit:
200
403 on submit (the JSON surface
names it; the HTML page route above uses the non-disclosing 404):
403
14. Render a hosted consent form
GET /api/v1/public/consent/{tenantId}/configenabled: false with empty
branding and copy.
200
enabled is
false:
200
15. Capture an opt-in or opt-out
POST /api/v1/public/consent200
422 with
the offending fields listed in details.issues:
422
403 CONSENT_PROOF_REQUIRED; opt-out ("optIn": false) never does.
16. Discover an agentic-commerce storefront
GET /api/v1/public/commerce/acp/{storefrontId}/.well-known/agentic-commerce{ data, meta } envelope — so a generic ACP
client parses the protocol document directly. Unknown or unpublished
storefronts 404.
200
17. Browse the hosted product feed
GET /api/v1/public/commerce/acp/{storefrontId}/feed200
18. Open an ACP checkout session
POST /api/v1/public/commerce/acp/{storefrontId}/checkoutmessages lists per-item problems (unknown product, out of stock); a
blocking error keeps the session not_ready_for_payment.
200
POST /api/v1/public/commerce/acp/{storefrontId}/checkout/update
re-prices the same session for a replacement item set — send the current
session plus the new items and read the re-derived totals the same way.
19. Complete the checkout under an agent mandate
POST /api/v1/public/commerce/acp/{storefrontId}/checkout/complete401s; an unverifiable signature 403s.
The response is RAW — the completed session plus the mandate and
authorization it ran under (shown here with the fields the route logs):
200