{"slug": "why-we-built-one-api-for-ai-research-media-and-editable-artifacts", "title": "Why we built one API for AI research, media, and editable artifacts", "summary": "3Stone AI released the 3Stone API, a single server-side API contract that unifies AI research, media generation, and editable artifact creation behind one authentication, job, and billing model. The API uses durable jobs with polling for creation endpoints and requires idempotency keys on every mutating request to prevent duplicate provider cost or output from blind retries. The company said it deliberately does not yet advertise public website/software execution or webhooks, and warned developers never to expose API keys in browser or mobile code.", "body_md": "A useful AI product often needs more than a text completion. It may need current research with sources, file understanding, generated media, an editable PowerPoint or spreadsheet, durable job state, storage, and usage accounting.\n\nBuilding each of those paths against a different provider creates a familiar problem: every integration has its own authentication, retry rules, status model, output format, and billing data. The first demo can be quick. The production system is not.\n\nThat is the problem we built the **3Stone API** to address: one server-side API contract for research, creation, and finished artifacts.\n\nSimple chat can complete synchronously:\n\n``` js\nconst response = await fetch(\"https://one.3stoneai.com/v1/chat\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.THREESTONE_API_KEY}`,\n    \"Idempotency-Key\": crypto.randomUUID(),\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    model: \"3stone-auto\",\n    input: \"Explain the tradeoffs between queues and scheduled polling.\",\n  }),\n});\n\nconst result = await response.json();\n```\n\nCreation endpoints use durable jobs. The initial request returns a job ID; clients poll that job and download the artifact only after it reaches a completed state.\n\n``` js\nconst headers = {\n  Authorization: `Bearer ${process.env.THREESTONE_API_KEY}`,\n  \"Content-Type\": \"application/json\",\n};\n\nconst submitted = await fetch(\n  \"https://one.3stoneai.com/v1/presentations\",\n  {\n    method: \"POST\",\n    headers: {\n      ...headers,\n      \"Idempotency-Key\": crypto.randomUUID(),\n    },\n    body: JSON.stringify({\n      prompt: \"Create a concise editable project update deck.\",\n    }),\n  },\n).then((response) => response.json());\n\nlet job;\ndo {\n  await new Promise((resolve) => setTimeout(resolve, 1500));\n  job = await fetch(\n    `https://one.3stoneai.com/v1/jobs/${submitted.job_id}`,\n    { headers },\n  ).then((response) => response.json());\n} while ([\"queued\", \"provider_starting\", \"running\"].includes(job.status));\n\nif (job.status !== \"completed\") {\n  throw new Error(`Job stopped: ${job.error?.code}`);\n}\n\nconst artifact = await fetch(\n  `https://one.3stoneai.com/v1/jobs/${submitted.job_id}/artifact`,\n  { headers },\n);\n```\n\nThe same job pattern applies to spreadsheets, images, and video.\n\nLong-running provider work can outlive an HTTP connection. A blind retry can create duplicate provider cost or duplicate customer-visible output. Every mutating request therefore accepts a stable idempotency key.\n\nIf the same key is reused with a different body, the API returns an idempotency conflict. If an accepted provider operation cannot yet be authoritatively reconciled, the request can enter a reconciliation-required state. Clients should preserve the request and job IDs instead of replaying the work.\n\nThat distinction matters: a network timeout does not prove that external execution failed.\n\nA research response is only useful when the application can retain and render its evidence:\n\n``` python\nimport json, os, urllib.request, uuid\n\nrequest = urllib.request.Request(\n    \"https://one.3stoneai.com/v1/research\",\n    data=json.dumps({\n        \"query\": \"Research current battery recycling policy and cite primary sources.\"\n    }).encode(),\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['THREESTONE_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),\n        \"Content-Type\": \"application/json\",\n    },\n    method=\"POST\",\n)\n\nwith urllib.request.urlopen(request, timeout=120) as response:\n    result = json.load(response)\n    print(result[\"output_text\"])\n    for source in result.get(\"sources\", []):\n        print(source[\"url\"])\n```\n\nThe current public release includes:\n\nWe deliberately do not advertise public API website/software execution or webhooks yet. Production truth matters more than a long launch list.\n\nNever expose a 3Stone API key in browser or mobile code. Put calls behind your authenticated backend or server function. Persist the returned request and job IDs so reconnecting clients can resume without duplicating work.\n\nUseful production error handling includes:\n\n`401 invalid_api_key`: reject and rotate/revoke as appropriate.` 402 insufficient_balance`: fund the usage balance before new provider work.` 409 idempotency_conflict`: use a new key only when the request body truly changes.` 429 rate_limit_exceeded`: back off with jitter.` reconciliation_required`: preserve identifiers and do not replay blindly.\n3Stone API is usage-based and separate from consumer subscriptions. Developer Mode exposes keys, balance, request logs, charges, and job state.\n\nI would especially value feedback on:\n\n**Quickstart, OpenAPI, and examples:** [https://github.com/jathanks3/3stone-developer-apis?utm_source=devto&utm_medium=content&utm_campaign=api_launch](https://github.com/jathanks3/3stone-developer-apis?utm_source=devto&utm_medium=content&utm_campaign=api_launch)\n\n**Documentation:** [https://www.3stoneai.com/developers/docs?utm_source=devto&utm_medium=content&utm_campaign=api_launch](https://www.3stoneai.com/developers/docs?utm_source=devto&utm_medium=content&utm_campaign=api_launch)\n\n**Developer Mode:** [https://one.3stoneai.com/developer?utm_source=devto&utm_medium=content&utm_campaign=api_launch](https://one.3stoneai.com/developer?utm_source=devto&utm_medium=content&utm_campaign=api_launch)\n\n*Disclosure: this article was prepared with AI assistance and reviewed by the 3Stone founder.*", "url": "https://wpnews.pro/news/why-we-built-one-api-for-ai-research-media-and-editable-artifacts", "canonical_source": "https://dev.to/jathanks3/why-we-built-one-api-for-ai-research-media-and-editable-artifacts-5flb", "published_at": "2026-09-28 18:24:39+00:00", "updated_at": "2026-09-28 18:50:43.573799+00:00", "lang": "en", "topics": ["ai-products", "ai-tools", "developer-tools", "generative-ai"], "entities": ["3Stone AI", "3Stone API"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/why-we-built-one-api-for-ai-research-media-and-editable-artifacts", "markdown": "https://wpnews.pro/news/why-we-built-one-api-for-ai-research-media-and-editable-artifacts.md", "text": "https://wpnews.pro/news/why-we-built-one-api-for-ai-research-media-and-editable-artifacts.txt", "jsonld": "https://wpnews.pro/news/why-we-built-one-api-for-ai-research-media-and-editable-artifacts.jsonld"}}