Sandbox & claim API

A sandbox is a real ShowroomPro ring builder that nobody owns yet. An agent or developer creates one with a single unauthenticated request, installs its snippet, and hands the jeweler a claim link. Claiming turns it into a normal account without changing the token, so nothing on the site has to change.

Base URL: https://www.showroompro.ai. CORS is open, so the API can also be called from a browser. The full schema is in the OpenAPI spec.

#Create a sandbox

POST /api/v1/sandboxes

bash
curl -s -X POST https://www.showroompro.ai/api/v1/sandboxes \
  -H "Content-Type: application/json" \
  -d '{"businessName":"Atelier Rose Jewelers","websiteUrl":"atelierrose.example","platform":"wix","source":"cursor"}'
js
const res = await fetch("https://www.showroompro.ai/api/v1/sandboxes", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ businessName: "Atelier Rose Jewelers", platform: "wix", source: "cursor" }),
});
const sandbox = await res.json();

#Request body

All fields are optional. An empty body works.

FieldTypeNotes
businessNamestringUp to 120 characters (longer values are cut). Pre-fills the claim form.
websiteUrlstringAn http(s) URL or a bare domain like example.com. Anything else returns 400.
platformstringshopify, wix, squarespace, wordpress, woocommerce, webflow, bigcommerce, custom or other. Unknown values are stored as other.
sourcestringYour agent or tool name, for example claude-code, cursor, codex, copilot. agent is accepted as an alias.

#Response: 201 Created

FieldDescription
objectAlways "sandbox".
apiVersionAPI version date, for example "2026-10-13".
idSandbox ID.
status"unclaimed".
quizTokenPublic token used by every snippet. Safe to put in page code.
quizUrlHosted quiz page. Works as a plain link (for example from Instagram or email).
claimUrlPrivate. Give it only to the jeweler. Don't commit it, put it in page code or post it publicly.
expiresAtISO timestamp when the unclaimed sandbox stops working.
renders{ limit, used, remaining } AI renders for the unclaimed sandbox.
snippetsinline, floating, popup and iframe HTML. See the widget reference.
businessEcho of name, websiteUrl and platform.
sourceNormalized source name.
notesPlain-language notes worth relaying to the user.

#Limits for unclaimed sandboxes

LimitValue
AI renders per sandbox3 in total
Lifetime14 days, then the quiz stops
Removal30 days after expiry; until then it can still be claimed
Create rate5 per IP per hour, 20 per IP per day

While unclaimed, a sandbox:

  • captures every lead. After the render limit, shoppers can still finish the quiz and their designs wait for the jeweler;
  • sends no emails to shoppers or to the jeweler, sends no alerts and fires no webhooks;
  • uses neutral branding and shows a small "Powered by ShowroomPro — unclaimed" note.

GET /api/v1/sandboxes returns the current limits and the request contract as JSON, so you can check them at runtime.

#Check status

GET /api/v1/sandboxes/status/{quizToken}

bash
curl -s https://www.showroompro.ai/api/v1/sandboxes/status/YOUR_TOKEN
json
{
  "object": "sandbox_status",
  "apiVersion": "2026-10-13",
  "id": "…",
  "status": "unclaimed",
  "claimed": false,
  "expiresAt": "2026-10-30T12:00:00.000Z",
  "renders": { "limit": 3, "used": 0, "remaining": 3 },
  "installDetected": true
}

status is unclaimed, claimed, expired or purged. installDetected becomes true once embed.js has loaded on a real (non-localhost) domain. No auth is needed because the quiz token is already public on the site.

#Errors

Errors share one shape:

json
{
  "object": "error",
  "apiVersion": "2026-10-13",
  "error": { "code": "invalid_request", "message": "websiteUrl must be an http(s) URL or domain such as example.com", "field": "websiteUrl" }
}
StatuscodeWhat to do
400invalid_requestFix the field named in field.
404not_foundStatus check only: no sandbox uses this token.
429rate_limitedToo many sandboxes from this network. Wait retryAfterSeconds (also in the Retry-After header), or send the user to signupUrl.
429capacity_exhaustedSandbox creation is paused. Same handling as rate_limited.
500internal_errorRetry once.

Don't create a new sandbox on every run. Create one per website and reuse its token.

#Claiming

The jeweler opens claimUrl and either:

  • creates an account. This starts a 7-day free trial. The sandbox's token, quiz and leads become theirs; or
  • signs in to an existing ShowroomPro account and merges the ring builder into it. The pasted snippet keeps working, and leads captured so far move into that account.

After claiming, the jeweler's normal plan limits, branding, emails and webhooks apply. The claim link only works once.

Claiming doesn't need any API call from the agent. Poll the status endpoint if you want to tell the user when it happened.