API Reference
The ShowTrust REST API lets your agent or backend create projects, configure widgets, fetch embed snippets, and read testimonials. All endpoints live under /v1.
Base URL: https://api.showtrust.to
Stability: endpoints under /v1 are stable. We add fields and endpoints freely; we don't rename or remove existing fields without a new version.
Authentication#
Every /v1/* request requires two headers, with one exception: POST /v1/auth/agent-init is public — it's how an agent obtains its credentials in the first place. The account ID identifies you, the API key proves it's you.
Responses use a { "message": "...", "data": ... } envelope. The real payload is always under data.
API key lifecycle#
- Each account has one active API key at a time. Regenerating from Settings → API replaces the previous key — the old one stops working immediately.
- The plaintext key is shown once on creation. If you lose it, you must regenerate. We only store a hash.
- Calling
POST /v1/auth/agent-initagain for the same email while the account is still unclaimed rotates the key — the prior key is invalidated. After the user claims the account (sets a password via the magic link), agent-init returns the “account already exists” branch instead.
Endpoints#
POST/v1/auth/agent-init
Public. Sign up (or recognize) a user from their email. Returns a fresh API key if the email is new; otherwise tells the agent the account already exists and to ask the user for their existing key.
Save accountId and apiKey. The plaintext key is shown once and never again. The user has expiresInDays to click the magic link in their inbox — after that the project is removed.
Re-running this endpoint for the same unclaimed email rotates the key: the previous apiKey stops working. If your agent retries, overwrite the old credentials with the new ones from the latest response.
No key is issued. The agent should ask the user to paste their existing API key from Settings → API in the dashboard. Only the legitimate account owner knows the key, so this naturally prevents account takeover via email enumeration.
5 requests/hour per IP, 3 requests/hour per email. Exceeding either returns 429.
400 — missing email, malformed email, or disposable-email domain.429 — rate limit exceeded.
GET/v1/me
Returns the account associated with the API key. Use this as a credential-validation check before any other call.
GET/v1/projects
List the projects on your account. Most recent first, capped at 50.
Each item is a full Project. status is "active" or "inactive" — new projects are always active. See GET /v1/projects/:id below for the full nested shape.
POST/v1/projects
Create a new project. The project owns its own collection page and widget configuration.
- When this is the account's very first project, the server auto-seeds ~6 generic demo testimonials (themed with
businessName) so the widget renders something on first install instead of an empty wall. - Demo entries get
source: "demo"andstatus: "demo". They render in the public widget alongside approved testimonials, but the dashboard tags them clearly and exposes a "Clear demo data" button at Project → Testimonials. - To skip seeding, pass
"skipDemoTestimonials": true. Ask the user if they want demos before calling — agents should not assume. - Programmatic cleanup is available via DELETE /v1/projects/:id/testimonials/demo.
Returns the full project including the auto-generated _id and default widgetConfig. The public collection page is https://app.showtrust.to/<slug>, where slug is data.publicPageConfig.slug — the value you sent in slug, or the slugified businessName if you omitted it. See GET /v1/projects/:id below for the full response shape.
- 400 with
"This slug is already taken. Please choose a different one."— another project already owns that slug. Ask the user for a different one and retry. - 402 with
code: "PROJECT_LIMIT_REACHED"— the account is at its project limit. Don't retry; surface the upgrade path.
GET/v1/projects/:id
Fetch a single project including its full public-page and widget configuration. This is the canonical project response shape — other endpoints that return a project return the same fields.
Fields: status is "active" or "inactive". The slug is set at creation time (see POST /v1/projects) and can't be renamed via v1 — manage it in the dashboard. Other fields inside publicPageConfig (logo, button colors, thank-you message, collected fields, etc.) are also dashboard-only today. See Not in v1 below.
404 — project not found, or the project doesn't belong to your account.
PATCH/v1/projects/:id/widget-config
Partial update of the widget's display configuration. Only the fields you send are changed.
400 — a value is outside the allowed enum range. 404 — project not found.
GET/v1/projects/:id/embed-snippet
Returns the embed snippet you (or your agent) paste into the user's website.
See the framework-specific recipes in Integrations for where to put script and container in your codebase.
POST/v1/projects/:id/testimonials
Create a single testimonial directly. Equivalent to adding one manually in the dashboard — created entries land as approved and visible immediately. Note: you no longer need this for first-install placeholders — the server auto-seeds demos when the first project is created (see POST /v1/projects).
- Created entries get
source: "manual"andstatus: "approved"— they show up in the widget immediately, with no review step. - The user can edit, pin, or delete them later from the dashboard at Project → Testimonials.
- Use for bulk-importing real testimonials from another source, or for adding one-offs (e.g. a quote the user dictated). For first-install placeholders, the server already auto-seeds — see POST /v1/projects.
400 — missing authorName or text, or a field failed validation (e.g. rating outside 1–5, value over max length).404 — project not found.
DELETE/v1/projects/:id/testimonials/demo
Bulk-delete all demo testimonials on a project. Call this once the user has added real testimonials and is ready to take the wall live.
- Deletes every testimonial on this project with
status: "demo". Approved, pending, and rejected entries are untouched. - Idempotent — calling it on a project with no demos returns
{ "deletedCount": 0 }and succeeds.
404 — project not found, or doesn't belong to your account.
GET/v1/projects/:id/testimonials
List publicly-visible testimonials for a project (approved + demo). Offset pagination.
- Visitors submit testimonials at the public collection page:
https://app.showtrust.to/<slug>(whereslugisproject.publicPageConfig.slug). Share this URL with your customers. - You can also add testimonials manually from the dashboard, or import them in bulk.
- New submissions land in
pendingand must be approved in the dashboard before they appear here. This endpoint returns testimonials withstatus: "approved"or"demo"— the same set that renders in the public widget.pendingandrejectedare dashboard-only. - On a brand-new account's first project, expect ~6 entries with
status: "demo"auto-seeded by the server (see POST /v1/projects). Wipe them with DELETE /v1/projects/:id/testimonials/demo once real ones come in. On subsequent projects the list starts empty. - Items are returned newest-first by
createdAt. Offset pagination is stable for already-collected testimonials, but newly approved ones will shift the offset of older items.
Optional fields (authorEmail, authorCompany, authorAvatar, twitter, rating, reviewedAt, pinned) are present only when set. The example below shows a fully-populated item.
Not in v1#
A few common actions aren't exposed via the API today — they're dashboard-only at app.showtrust.to. If you need one of these, send users to the dashboard rather than hunt for a missing endpoint.
- Logo upload and the rest of the public-page styling (
logo,buttonColor,buttonTextColor,thankYouMessage,theme,showConfetti,collectFields) — manage at Project → Public Page. - Testimonials: approve / reject / pin / edit / delete — manage at Project → Testimonials. The v1 API can create approved testimonials (see POST /v1/projects/:id/testimonials) and list approved ones, but the moderation actions are dashboard-only.
- Project deletion — manage at Project → Settings.
- Subscription / billing — manage at Account → Billing.
- Slug rename — you can choose the slug at project-creation time via POST /v1/projects, but renaming an existing project's slug is dashboard-only today.
Errors#
All errors return a JSON body with a message field: