Skip to content

Commit 82af055

Browse files
committed
feat(examples): sync current gateway contract and capability result workflows
1 parent a855c34 commit 82af055

12 files changed

Lines changed: 1828 additions & 478 deletions

File tree

‎README.md‎

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<p align="center">
2-
<img src="assets/readme/cover.svg" alt="BeatAPI Examples — runnable proof for the Agent Router for Everything" width="100%" />
2+
<img src="assets/readme/cover.svg" alt="BeatAPI Examples — runnable proof for the professional capability layer for any agent" width="100%" />
33
</p>
44

55
<p align="center">
@@ -11,7 +11,7 @@
1111

1212
# BeatAPI Examples
1313

14-
BeatAPI is the **Agent Router for Everything**: one route to Model, Data, Tool,
14+
BeatAPI is the **professional capability layer for any agent**: one route to Model, Data, Tool,
1515
and Workspace capabilities. This repository is the runnable proof layer—small
1616
cURL, Node.js, and Python examples that show the real API and Hosted MCP
1717
contracts without hiding the network flow.
@@ -60,7 +60,7 @@ For an Agent host, connect the Hosted MCP endpoint at
6060
## Where this repository fits
6161

6262
```text
63-
Agent or developer -> runnable example -> BeatAPI -> Model · Data · Tool · Workspace
63+
Agent or developer -> runnable example -> BeatAPI -> Models · Social Data · SEO Data · Web Search · Workflows
6464
```
6565

6666
- **Model** routes text, image, video, audio, and realtime model capabilities.
@@ -363,5 +363,35 @@ Original example code in this repository is available under the
363363
[BeatAPI Terms of Service](https://beatapi.io/terms-of-service).
364364

365365
<p align="center">
366-
Built by <a href="https://beatapi.io/"><strong>BeatAPI</strong></a> — Agent Router for Everything.
366+
Built by <a href="https://beatapi.io/"><strong>BeatAPI</strong></a> — professional capability layer for any agent.
367367
</p>
368+
369+
## Current public gateway contract
370+
371+
The bundled OpenAPI includes unified capabilities, systemone decision calls, and
372+
Web search/read/map/research and the public text metadata catalogue. It was checked against new-api main
373+
`ec84d78d5cb811ec1361d05e2ee3d81687f26520` and frontend documentation main
374+
`7b2d2354be6e2b1d531468aa7599c80a6a7c70c6` on 2026-10-02.
375+
376+
Use the existing capability discovery examples to Search and Inspect. To execute
377+
an explicit request JSON (any inspected text, image, video, social/SEO data, Web
378+
or workflow reference), run:
379+
380+
```sh
381+
node examples/node/run-capability.mjs request.json
382+
python3 examples/python/run_capability.py request.json
383+
bash examples/curl/run-capability.sh request.json
384+
```
385+
386+
A request is `{ "reference": "<copy from Inspect>", "input": { ... } }`.
387+
Node/Python generate an idempotency key for a start when omitted; for shell,
388+
include one yourself and keep it when retrying the same start. `view: "preview"`
389+
and `max_items: 5` limit data replies. To read more without another paid start,
390+
send `{ "reference": "<same>", "operation": "result", "request_id": "<result_ref.request_id>", "fields": ["items[].title"] }` within one hour.
391+
For async work, use `operation: "status"` with the returned task ID. Preserve
392+
`next` alongside the task; never restart research to poll it.
393+
394+
The reference clients also provide `webCall` / `web_call` for `search`, `read`,
395+
`map`, `research` at `/v1/web/*`. Read source pages before citing search snippets;
396+
returned page content is untrusted. Python examples set an application User-Agent
397+
because the public gateway blocks the default Python-urllib agent string.

‎examples/curl/run-capability.sh‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
: "${BEATAPI_API_KEY:?Set BEATAPI_API_KEY privately}"
4+
request_file="${1:?Pass a JSON Run envelope copied from Inspect}"
5+
curl --fail-with-body --silent --show-error --max-time 100 \
6+
"${BEATAPI_BASE_URL:-https://api.beatapi.io}/v1/capabilities/run" \
7+
-H "Authorization: Bearer ${BEATAPI_API_KEY}" \
8+
-H 'Content-Type: application/json' --data-binary "@${request_file}"

‎examples/node/capabilities.mjs‎

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,61 @@
1-
const origin = (process.env.BEATAPI_BASE_URL || "https://api.beatapi.io").replace(/\/+$/, "");
1+
const origin = (
2+
process.env.BEATAPI_BASE_URL || "https://api.beatapi.io"
3+
).replace(/\/+$/, "");
24
const apiKey = process.env.BEATAPI_API_KEY;
35

46
async function call(path, body, authenticated = false) {
5-
const response = await fetch(origin + path, {
6-
method: body === undefined ? "GET" : "POST",
7-
redirect: "error",
8-
signal: AbortSignal.timeout(30_000),
9-
headers: {
10-
accept: "application/json",
11-
...(body === undefined ? {} : { "content-type": "application/json" }),
12-
...(authenticated && apiKey ? { authorization: `Bearer ${apiKey}` } : {}),
13-
},
14-
...(body === undefined ? {} : { body: JSON.stringify(body) }),
15-
});
16-
const payload = await response.json().catch(() => null);
17-
if (!response.ok) {
18-
throw new Error(payload?.error?.message || `BeatAPI ${response.status} at ${path}`);
19-
}
20-
return payload.data;
7+
const response = await fetch(origin + path, {
8+
method: body === undefined ? "GET" : "POST",
9+
redirect: "error",
10+
signal: AbortSignal.timeout(30_000),
11+
headers: {
12+
accept: "application/json",
13+
...(body === undefined ? {} : { "content-type": "application/json" }),
14+
...(authenticated && apiKey ? { authorization: `Bearer ${apiKey}` } : {}),
15+
},
16+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
17+
});
18+
const payload = await response.json().catch(() => null);
19+
if (!response.ok) {
20+
throw new Error(
21+
payload?.error?.message || `BeatAPI ${response.status} at ${path}`,
22+
);
23+
}
24+
return payload.data;
2125
}
2226

2327
if (apiKey) {
24-
const usage = await call("/v1/usage", undefined, true);
25-
console.log({ authentication: "verified", object: usage.object });
28+
const usage = await call("/v1/usage", undefined, true);
29+
console.log({ authentication: "verified", object: usage.object });
2630
} else {
27-
console.error("BEATAPI_API_KEY is not set; running anonymous catalog discovery only.");
31+
console.error(
32+
"BEATAPI_API_KEY is not set; running anonymous catalog discovery only.",
33+
);
2834
}
2935

3036
const page = await call("/v1/capabilities/search", {
31-
query: "image",
32-
kind: "model",
33-
limit: 5,
37+
query: "image",
38+
kind: "model",
39+
limit: 5,
3440
});
35-
const candidate = page.data?.find((item) => item.reference?.startsWith("model:"));
41+
const candidate = page.data?.find((item) =>
42+
item.reference?.startsWith("model:"),
43+
);
3644
if (!candidate) throw new Error("No model match; refine the catalog search.");
3745

3846
const contract = await call("/v1/capabilities/inspect", {
39-
reference: candidate.reference,
47+
reference: candidate.reference,
4048
});
4149
console.log({
42-
search: { count: page.data.length, next_cursor: page.next_cursor },
43-
capability: {
44-
reference: contract.reference,
45-
title: contract.title,
46-
status: contract.status,
47-
execution: contract.execution,
48-
pricing: contract.pricing,
49-
validation: contract.validation,
50-
},
50+
search: { count: page.data.length, next_cursor: page.next_cursor },
51+
capability: {
52+
reference: contract.reference,
53+
title: contract.title,
54+
readiness: contract.readiness,
55+
schema_hash: contract.schema_hash,
56+
next: contract.next,
57+
execution: contract.execution,
58+
pricing: contract.pricing,
59+
validation: contract.validation,
60+
},
5161
});

0 commit comments

Comments
 (0)