Particle for developers
Quick start
Use Particle from your own app
- Add funds to your Agent Pool. The API pays from it, never from your Plus allowance.
- Make a key in the chat's Settings, API keys. It is shown once; keep it secret.
- Send it on every call:
Authorization: Bearer pk_live_...
curl https://particlebuddy.com/v1/chat/completions \
-H "Authorization: Bearer $PARTICLE_KEY" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"Hi!"}]}'
Base address https://particlebuddy.com/v1. Works with OpenAI client libraries: set the base URL and your key.
Chat
POST /v1/chat/completions
The OpenAI request and answer shape. Particle picks the best model for each message, so model is ignored and answers say "model": "particle". max_tokens goes up to 4096 (default 1024).
{"id":"chatcmpl-...","object":"chat.completion","model":"particle",
"choices":[{"index":0,"message":{"role":"assistant","content":"Hello!"},
"finish_reason":"stop"}],
"usage":{"prompt_tokens":9,"completion_tokens":3,"total_tokens":12}}
Streaming: add "stream": true for server-sent events in OpenAI chunks, ending with data: [DONE]. Add "stream_options": {"include_usage": true} for a last usage chunk.
Agents
Start an agent run
Turn on "Allow API access" on the agent's page first. GET /v1/agents lists your agents and their ids.
curl https://particlebuddy.com/v1/agents/AGENT_ID/runs \
-H "Authorization: Bearer $PARTICLE_KEY" -H "Content-Type: application/json" \
-d '{"input":"Find three facts about lighthouses",
"callback_url":"https://example.com/particle-hook"}'
curl https://particlebuddy.com/v1/runs/RUN_ID \
-H "Authorization: Bearer $PARTICLE_KEY"
The start answers 202 with the run id. Poll GET /v1/runs/{id} every few seconds: status is queued, running, waiting_approval, done, failed or cancelled, with result and cost when it ends. Or give a callback_url (public https) and Particle POSTs the result there when the run ends.
Pricing
Pay as you go, at twice the model cost
Every call is charged from your Agent Pool at what the AI model and paid tools really cost Particle, times two. No monthly fee. Each charge shows in your pool and on the agent's page.
- 1,000 short messages (a sentence or two each way): about $1 to $2 CAD.
- 1,000 longer messages (a page in, a few paragraphs out): about $4 to $5 CAD.
- An agent's web search: about 6 cents CAD each; reading a page, under a cent.
These are estimates; you pay the real cost of each call, times two. Before a call the pool must cover the most it could cost; the real, usually lower, price is charged after.
Limits and errors
Limits and errors
Each key has its own limits, set in Settings, API keys: requests a minute (default 60), agent runs a day (default 100) and the most it may spend a month in CAD.
401no key, a wrong key or a revoked key.402the pool or the key's monthly cap cannot cover the call (insufficient_funds,key_spend_cap).403API access is off for that agent.404not found.429too many requests or runs: waitRetry-Afterseconds.503maintenance, or Particle is busy: try again soon.
{"error":{"message":"Your Agent Pool cannot cover this request.",
"type":"insufficient_funds","code":"insufficient_funds"}}Webhooks
Check that a result came from Particle
Results sent to a web address (a task's "Send results to a web address", or a callback_url) are JSON: agent, task, title, result_text, files, images, sources, finished_at. Each carries X-Particle-Signature: t=<time>,v1=<HMAC-SHA256>, made with the agent's signing secret (agent page, Connect to Zapier, Make or n8n).
import crypto from "node:crypto";
function fromParticle(rawBody, header, secret) {
const p = Object.fromEntries(header.split(",").map((x) => x.split("=")));
if (Math.abs(Date.now() / 1000 - Number(p.t)) > 300) return false;
const want = crypto.createHmac("sha256", secret)
.update(`${p.t}.${rawBody}`).digest("hex");
return want.length === String(p.v1).length &&
crypto.timingSafeEqual(Buffer.from(want), Buffer.from(p.v1));
}
Particle tries three times (10 seconds each) and lists every delivery in the agent's activity.