Verification API
Machine access to the check behind /verify. You send a URL to an audio file and a webhook; Huebsch fetches the file, checks signature and watermark, and POSTs the signed result to your webhook. See AI Provenance for what the check confirms.
Endpoint
POST /api/verify
Authorization: Bearer {token}Unlike other endpoints, the token goes in the Authorization header, not in the path. It is a personal access token with the use Verification API, created at /account/tokens. Such a token checks files only and reads no data. Media, fact-checkers and researchers get an account with unlimited checks on request: hi@schoenreden.com.
Quick Test
curl -X POST https://huebsch.schoenreden.com/api/verify \
-H "Authorization: Bearer hbm_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/episode.mp3","webhook":"https://example.com/hooks/huebsch","requestId":"episode-42"}'Request Body
{
"url": "https://example.com/episode.mp3",
"webhook": "https://example.com/hooks/huebsch",
"requestId": "episode-42"
}Fields
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The audio file. https on port 443, no credentials, a public address. Up to 200 MB and three hours; up to three redirects are followed. |
webhook | string | Yes | Where the result is POSTed. Same rules as url. |
requestId | string | No | Your id for this check (1–64 chars, A-Z a-z 0-9 . _ -). For seven days, repeating it returns the same check and reference, counted once; the result is delivered once. Reusing it with other URLs fails with 409.2. Without it, every request is a new check. |
Response
Success
202 Accepted
{ "ok": true, "val": { "reference": "3f9a2c8e" } }The reference identifies the check in the result and when you contact Huebsch.
Error
{ "ok": false, "val": { "error": "URL not allowed", "code": "422.11" } }| Code | Meaning |
|---|---|
401.1 | No bearer token |
401.2 | Unknown or expired token, or not a Verification API token |
409.2 | requestId already used with other URLs |
422.1 | Body is not JSON |
422.2 | Body fails validation (issues lists why) |
422.11 | A URL is not allowed |
429.2 | Too many checks: 20 per hour and 200 per day per account |
429.3 | Too many checks for this host: 60 per hour per file host (redirect targets included) and per webhook host, for all callers together |
503.11 | Unable to accept the check; retry later |
Webhook
When the check ends, Huebsch POSTs to your webhook:
{
"ok": true,
"val": {
"reference": "3f9a2c8e",
"requestId": "episode-42",
"result": "eyJhbGciOiJFUzI1NiIsIng1YyI6Wy..."
}
}result is the signed result, the same one /verify offers for download. Verify it before you trust it: a compact JWS (ES256) whose x5c certificate chains to the Huebsch root at /.well-known/c2pa/root.pem, as of its checkedAt. The payload is described under Signed result. The envelope around it is not signed.
When there is no result:
{ "ok": false, "val": { "error": "Download failed", "code": "422.12", "reference": "3f9a2c8e", "requestId": "episode-42" } }| Code | Meaning |
|---|---|
422.12 | The file could not be fetched: unreachable, not found, too large or too slow. No further reason is given. |
503.12 | The check could not be completed; try again later |
Delivery counts as successful on a 2xx answer within 10 seconds. A delivery is tried up to five times over about an hour; redirects are not followed. The headers User-Agent and X-Huebsch-Delivery-Id are the same as for production webhooks.
Signed result
The same result /verify offers for download.
- Signature:
ES256, withx5ccarrying the signing certificate only. - Payload:
v(format version, now2),method(version of the check's rules),detector,checkedAt,sha256of the checked file,reference,verdict,details. - Verdict kinds:
signed,watermark,signatureMismatch,unconfirmedSignature,none,rejected. Results of format1may carrymatch,excerpt,alteredorunplaced; read them aswatermark. - Validity: the certificate chains to the Huebsch root and is checked as of
checkedAt, so results outlive their signer.checkedAtis asserted by the signer.
Usage
- The file is fetched once, held in memory for the check and not stored. The result is deleted once delivered.
- Checks run one at a time; expect a few minutes when several are queued.