cd /news/ai-products/why-we-built-one-api-for-ai-research… · home › topics › ai-products › article
[ARTICLE · art-141211] src=dev.to ↗ pub= topic=ai-products verified=true sentiment=↑ positive

Why we built one API for AI research, media, and editable artifacts

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.

by read3 min views1 publishedSep 28, 2026

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.

Building 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.

That is the problem we built the 3Stone API to address: one server-side API contract for research, creation, and finished artifacts.

Simple chat can complete synchronously:

const response = await fetch("https://one.3stoneai.com/v1/chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.THREESTONE_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "3stone-auto",
    input: "Explain the tradeoffs between queues and scheduled polling.",
  }),
});

const result = await response.json();

Creation 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.

const headers = {
  Authorization: `Bearer ${process.env.THREESTONE_API_KEY}`,
  "Content-Type": "application/json",
};

const submitted = await fetch(
  "https://one.3stoneai.com/v1/presentations",
  {
    method: "POST",
    headers: {
      ...headers,
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify({
      prompt: "Create a concise editable project update deck.",
    }),
  },
).then((response) => response.json());

let job;
do {
  await new Promise((resolve) => setTimeout(resolve, 1500));
  job = await fetch(
    `https://one.3stoneai.com/v1/jobs/${submitted.job_id}`,
    { headers },
  ).then((response) => response.json());
} while (["queued", "provider_starting", "running"].includes(job.status));

if (job.status !== "completed") {
  throw new Error(`Job stopped: ${job.error?.code}`);
}

const artifact = await fetch(
  `https://one.3stoneai.com/v1/jobs/${submitted.job_id}/artifact`,
  { headers },
);

The same job pattern applies to spreadsheets, images, and video.

Long-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.

If 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.

That distinction matters: a network timeout does not prove that external execution failed.

A research response is only useful when the application can retain and render its evidence:

import json, os, urllib.request, uuid

request = urllib.request.Request(
    "https://one.3stoneai.com/v1/research",
    data=json.dumps({
        "query": "Research current battery recycling policy and cite primary sources."
    }).encode(),
    headers={
        "Authorization": f"Bearer {os.environ['THREESTONE_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
        "Content-Type": "application/json",
    },
    method="POST",
)

with urllib.request.urlopen(request, timeout=120) as response:
    result = json.load(response)
    print(result["output_text"])
    for source in result.get("sources", []):
        print(source["url"])

The current public release includes:

We deliberately do not advertise public API website/software execution or webhooks yet. Production truth matters more than a long launch list.

Never 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.

Useful production error handling includes:

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. 3Stone API is usage-based and separate from consumer subscriptions. Developer Mode exposes keys, balance, request logs, charges, and job state.

I would especially value feedback on:

Quickstart, OpenAPI, and examples: https://github.com/jathanks3/3stone-developer-apis?utm_source=devto&utm_medium=content&utm_campaign=api_launch

Documentation: https://www.3stoneai.com/developers/docs?utm_source=devto&utm_medium=content&utm_campaign=api_launch

Developer Mode: https://one.3stoneai.com/developer?utm_source=devto&utm_medium=content&utm_campaign=api_launch

Disclosure: this article was prepared with AI assistance and reviewed by the 3Stone founder.

── more in #ai-products 4 stories · sorted by recency
── more on @3stone ai 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/why-we-built-one-api…] indexed:0 read:3min 2026-09-28 · —