بحث. Describe. Quote. Run.
GET /api/capabilities searches by natural-language query and category. Describe the selected slug before constructing input: its schema is the source of truth for حقول, pricing, ملف requirements, and execution support.
- بحثFind candidates with
?q=ضغط%20pdf. - DescribeRead
execution.machine_run_statusand the input schema. - QuoteConfirm price, wallet clearance, and save the returned
quote_id. - تشغيلSend the same input, quote ID, and a unique idempotency key.
export SWARME_API_KEY="YOUR_SWARME_API_KEY"
export SWARME_BASE_URL="https://YOUR_SWARME_HOST"
curl "$SWARME_BASE_URL/api/capabilities?q=ضغط%20pdf&limit=10"
curl "$SWARME_BASE_URL/api/capabilities/compress-pdf"
curl -X POST "$SWARME_BASE_URL/api/capabilities/uuid-generator/quote" \
-H "Authorization: Bearer $SWARME_API_KEY" -H "Content-Type: application/json" \
-d '{"input":{},"client_type":"api"}'
curl -X POST "$SWARME_BASE_URL/api/capabilities/uuid-generator/run" \
-H "Authorization: Bearer $SWARME_API_KEY" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" -H "Content-Type: application/json" \
-d '{"input":{},"client_type":"api","quote_id":"YOUR_QUOTE_ID"}'Authenticate with least privilege.
إنشاء a scoped API key from Dashboard → Developers. Send Authorization: Bearer YOUR_SWARME_API_KEY. Never put a key in client-side code, URLs, logs, or a repository.
Scopes
Use only the needed scopes: capabilities:read, capabilities:quote, capabilities:run, uploads:write, artifacts:read, and billing:read.
Spend limits
Each client may have a USD cap. Check GET /api/account/balance before paid work; wallet or spend-limit failures are hard stops.
Idempotency
Use one stable Idempotency-Key per logical quote/run attempt. Replays return the original work; a key cannot safely represent different input. Paid API runs may require it.
Quotes
Quote immediately before execution and pass its quote_id. Surface the price or policy failure إلى the user.
Use short-lived رفع sessions.
إنشاء a session for the selected slug, رفع raw bytes إلى its returned URL with the dedicated token, then supply رفع_id (or رفع_ids) in quote and run input. Validate filename, MIME type, and الحجم against describe. Never reuse or log an رفع token.
# إنشاء a session. Keep its رفع_token private.
curl -X POST "$SWARME_BASE_URL/api/capabilities/compress-pdf/upload-session" \
-H "Authorization: Bearer $SWARME_API_KEY" -H "Content-Type: application/json" \
-d '{"input":{"filename":"مستند.PDF","content_type":"application/PDF","الحجم_bytes":12345},"client_type":"api"}'
# Read رفع_url and رفع_token from the response, then:
curl -X PUT "YOUR_رفع_URL" -H "Authorization: Bearer YOUR_رفع_TOKEN" \
-H "Content-Type: application/PDF" --data-binary @مستند.PDF
# Quote and run with رفع_id; then poll /api/capability-runs/YOUR_RUN_ID.Poll status; cancel cooperatively.
GET /api/capability-runs/{run_id}Read queued, running, retrying, completed, failed, or cancelled state.POST /api/capability-runs/{run_id}/cancelCancel queued work or request cooperative cancellation.GET /api/capability-runs/{run_id}/artifactsList permission-checked artifacts, then follow their تنزيل روابط.machine_run_status is a safety gate
The canonical values are supported, requires_worker, باقة_only, and describe_only. supported executes in the declared mode. requires_worker preserves the worker-required response until that runtime is ready. باقة_only returns a client باقة without server processing. describe_only blocks quote/run. The legacy value runnable is accepted as supported for backward compatibility. Treat missing or unknown values as describe_only and re-describe before execution.
The same safe flow, as tools.
Connect a streamable HTTP client إلى https://swarme.io/ar/mcp. Begin with tools/list; do not assume a cached list.
swarme_capabilities_بحثswarme_capability_describeswarme_account_balanceswarme_أداة_quoteswarme_أداة_runswarme_أداة_statusswarme_أداة_cancelswarme_أداة_artifactsswarme_رفع_session_إنشاءInspect machine_run_status after describe. Quote/run only supported, requires_worker, or باقة_only; refuse describe_only, missing, and unknown values. Keep approval boundaries around paid runs and ملف access.
{
"mcpServers": {
"swarme": {
"type": "streamable-http",
"url": "https://YOUR_SWARME_HOST/mcp",
"الرؤوس": { "Authorization": "Bearer ${SWARME_API_KEY}" }
}
}
}Version and deprecate contracts explicitly.
The contract manifest inventories REST, MCP tools, execution and run states, quote/run and ملف lifecycles, errors, and scopes. The machine-readable changelog classifies changes as additive, behavioral-risk, or breaking. Unknown manifest elements fail compatibility checks conservatively.
تشغيل php bin/check-contract-compatibility.php --baseline=BASELINE.json --candidate=CANDIDATE.json locally or in CI. Breaking changes fail unless their stable change IDs appear in an explicit local approvals ملف.
Deprecation convention
When deprecation is activated for an element, publish manifest deprecated البيانات الوصفية and use standard Deprecation, Sunset, and رابط: <...>; rel=deprecation الرؤوس plus Swarme-Contract-Version. The configured target is at least 90 days' notice when practical. It is a governance target—not an SLA—and urgent أمان, legal, abuse-prevention, or uncontrollable upstream changes may require less notice. This increment configures and مستندات the convention only; it does not deprecate or إزالة any endpoint.
Use any HTTP client.
These examples use environment variables and placeholders only. They contain no credentials. The source distribution also includes copyable, dependency-free examples/rest-agent.php و examples/mcp-agent.php recipes covering بحث through artifacts or cancellation, with an explicit --approve boundary and optional --file=PATH رفع.
Before integration, run php bin/check-agent-contract.php against bundled versioned fixtures. Supplying --base-url=URL is explicit and performs only read-only public discovery checks. These are reusable starter clients—not a generated SDK or a frozen SDK API.
const baseUrl = process.env.SWARME_BASE_URL ?? "https://YOUR_SWARME_HOST";
const apiKey = process.env.SWARME_API_KEY;
if (!apiKey) throw new Error("Set SWARME_API_KEY");
const request = async (path: string, init: RequestInit = {}) => {
const response = await fetch(`${baseUrl}${path}`, {
...init,
الرؤوس: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", ...init.الرؤوس },
});
if (!response.ok) throw new Error(`${response.status}: ${await response.نص()}`);
return response.json();
};
const described = await request("/api/capabilities/uuid-generator");
const rawStatus = described.capability?.execution?.machine_run_status;
const machineStatus = rawStatus === "runnable" ? "supported" : rawStatus;
const allowedStatuses = new Set(["supported", "requires_worker", "باقة_only"]);
if (!allowedStatuses.has(machineStatus)) throw new Error("Capability is describe-only; describe again before execution");
const quote = await request("/api/capabilities/uuid-generator/quote", {
method: "POST", body: JSON.stringify({ input: {}, client_type: "api" }),
});
const run = await request("/api/capabilities/uuid-generator/run", {
method: "POST", الرؤوس: { "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ input: {}, client_type: "api", quote_id: quote.quote.quote_id }),
});
const status = await request(`/api/capability-runs/${run.run_id}`);import os, uuid, requests
base_url = os.getenv("SWARME_BASE_URL", "https://YOUR_SWARME_HOST")
api_key = os.environ["SWARME_API_KEY"]
الرؤوس = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
described = requests.get(f"{base_url}/api/capabilities/uuid-generator", الرؤوس=الرؤوس, timeout=30).json()
raw_status = described.get("capability", {}).get("execution", {}).get("machine_run_status")
machine_status = "supported" if raw_status == "runnable" else raw_status
if machine_status not in {"supported", "requires_worker", "باقة_only"}:
raise RuntimeError("Capability is describe-only; describe again before execution")
quote = requests.post(
f"{base_url}/api/capabilities/uuid-generator/quote",
الرؤوس=الرؤوس, json={"input": {}, "client_type": "api"}, timeout=30,
).json()
run = requests.post(
f"{base_url}/api/capabilities/uuid-generator/run",
الرؤوس={**الرؤوس, "Idempotency-Key": str(uuid.uuid4())},
json={"input": {}, "client_type": "api", "quote_id": quote["quote"]["quote_id"]}, timeout=30,
).json()
status = requests.get(f"{base_url}/api/capability-runs/{run['run_id']}", الرؤوس=الرؤوس, timeout=30).json()