I’m the founder of 3Stone AI. One lesson from building our API was that a successful generation request is only part of the job. The output still has to arrive, open, and be usable.
A provider can return “success” while a customer still has no usable file. The durable product contract is longer:
request → persisted job → provider work → stored artifact → authenticated download → file opens
Below is the production contract we use for an editable Word document. You need a 3Stone API key and funded API balance. Keep the key in an environment variable; never paste it into source control.
1. Submit one artifact request
export THREESTONE_API_KEY="your-key-from-developer-mode"
curl -sS https://one.3stoneai.com/v1/documents \
-H "Authorization: Bearer $THREESTONE_API_KEY" \
-H "Idempotency-Key: onboarding-brief-2026-10-06-001" \
-H "Content-Type: application/json" \
-d '{"prompt":"Create a polished two-page onboarding brief for a small software team. Include goals, roles, a first-week checklist, and success criteria."}'
A newly accepted request returns HTTP 202 with a durable job_id and a status such as queued.
{
"object": "response",
"capability": "documents",
"job_id": "<uuid>",
"status": "queued"
}
The API accepts prompts from 1 to 8,000 characters. The idempotency key must be 8–200 safe characters.
2. Poll the job instead of guessing
JOB_ID="the-job-id-from-step-1"
curl -sS "https://one.3stoneai.com/v1/jobs/$JOB_ID" \
-H "Authorization: Bearer $THREESTONE_API_KEY"
The same account boundary applies to job status and artifact access. A completed response exposes artifact metadata; internal storage paths and provider request IDs are not returned.
A minimal shell loop could look like this:
while true; do
BODY=$(curl -sS "https://one.3stoneai.com/v1/jobs/$JOB_ID" \
-H "Authorization: Bearer $THREESTONE_API_KEY")
STATUS=$(printf '%s' "$BODY" | jq -r '.status')
printf 'status=%s\n' "$STATUS"
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && exit 1
[ "$STATUS" = "reconciliation_required" ] && exit 2
sleep 3
done
3. Download the artifact with the same key
curl -sS "https://one.3stoneai.com/v1/jobs/$JOB_ID/artifact" \
-H "Authorization: Bearer $THREESTONE_API_KEY" \
--output onboarding-brief.docx
Then validate the thing the customer actually receives:
file onboarding-brief.docx
unzip -t onboarding-brief.docx
Those checks confirm the download is an Office package, not an HTML error page saved with a .docx extension. The next layer is product-specific: open it in Word or LibreOffice, inspect headings and lists, edit it, save it, reopen it, and confirm the revision survived.
The lifecycle at a glance
POST /v1/documents + Idempotency-Key
│
▼
202 + durable job_id
│
▼
GET /v1/jobs/{id}
queued → running → completed
│
▼
GET /v1/jobs/{id}/artifact
│
▼
open → inspect → edit → save → reopen
Safe retries and billing
Idempotency is part of the billing boundary, not just a convenience.
- Reusing the same key with the same request replays the original admission instead of starting unrelated duplicate work.
- Reusing that key with a different payload returns HTTP 409
idempotency_conflict. - HTTP 402 means the account needs balance before retrying with a new key.
- HTTP 429 enforces the current per-key rate limit of 60 requests per minute.
- A reconciliation response is not permission to fire a fresh paid request. Keep the original job and request identifiers and let the uncertain outcome reconcile.
In our implementation, money is reserved before work starts. Completed work settles against measured usage. Failures are either finalized or moved into an explicit reconciliation state when the provider or artifact-storage outcome is uncertain. That distinction matters: blindly generating a new idempotency key can turn uncertainty into a duplicate charge.
Repairs that changed how we verify output
Real customer failures forced us to stop treating a green request as the definition of success. We now separate several states that used to be easy to flatten:
- the controller accepted the request;
- a worker actually claimed it;
- the provider returned;
- the artifact was stored;
- the authenticated download returned the intended media type;
- the file opened and remained editable.
The same lesson applies beyond DOCX. A spreadsheet needs formulas and a workbook that recalculates. A presentation needs editable slide objects, not a screenshot in a PPTX container. A media job needs a playable export with the requested audio behavior.
I built 3Stone AI with substantial Codex assistance, including implementation and verification work. I’m sharing the contract here because the most useful feedback is concrete: does this job model make integration and recovery clear, and which artifact validation signal would you want returned by the API?
The current developer surface and supported endpoints are at 3stoneai.com/developers.
Top comments (0)