Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions docs/api-reference/realface.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ You can use the web UI at [blockrun.ai/studio/realface](https://blockrun.ai/stud
```
[1] POST /v1/realface/init — FREE, rate-limited
body: { "name": "..." }
→ { group_id: "legacy_rf_…",
→ { group_id: "rf1_…",
h5_link: "https://kyc.byteintl.com/?...",
expires_in_seconds: 120 }

Expand All @@ -35,7 +35,7 @@ You can use the web UI at [blockrun.ai/studio/realface](https://blockrun.ai/stud
record a 2-4 second video doing two prompted actions (nod, blink).
NO login, NO ID upload, NO personal info.

[3] GET /v1/realface/status?groupId=legacy_rf_… — poll every 3-5s
[3] GET /v1/realface/status?groupId=rf1_… — poll every 3-5s
→ { status: "pending_validation", ready_to_finalize: false }
→ ... (after H5 completes)
→ { status: "active", ready_to_finalize: true }
Expand Down Expand Up @@ -67,21 +67,25 @@ POST https://blockrun.ai/api/v1/realface/init
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Display name for your reference (1–64 chars). Stored upstream + in your list |
| `groupId` | string | No | If set, refresh the h5Link for this existing group instead of creating a new one. Use when the original 120s session expired |
| `groupId` | string | No | If set, refresh the h5Link for this existing group instead of creating a new one. Pass the `group_id` a previous `/init` returned, verbatim. Use when the original 120s session expired |

### Response

```json
{
"object": "realface.init",
"group_id": "legacy_rf_8137",
"group_id": "rf1_…",
"h5_link": "https://kyc.byteintl.com/?accessKeyId=...&sessionToken=...&configId=...",
"status": "pending_validation",
"expires_in_seconds": 120,
"next_steps": { ... }
}
```

:::note{title="group_id is an opaque handle"}
`group_id` is a ~215-character opaque handle, not an identifier you can construct, parse or guess. Store it and pass it back **verbatim** to `/status`, `/enroll` and the `/init` refresh path. It is scoped to the group it was issued for, so treat it as the credential for that enrollment — anyone holding it can refresh the H5 link and enroll into the group.
:::

### Rate limiting

Free but **rate-limited to 10 init calls per hour per IP** because each call generates an upstream session (real cost). For honest single-user usage this is plenty; if you hit `429` (`{ "error": "Rate limit exceeded", "retryAfterSeconds": n }` with a `Retry-After` header), wait or use the refresh path on an existing group. The refresh response carries `"refreshed": true` and no `next_steps`. An upstream failure on either path is `502`.
Expand Down Expand Up @@ -136,15 +140,15 @@ The H5 link works in any modern browser with a webcam. The rights-holder can ope
:::step{title="Poll for completion (FREE)"}

```
GET https://blockrun.ai/api/v1/realface/status?groupId=legacy_rf_
GET https://blockrun.ai/api/v1/realface/status?groupId=rf1_
```

### Response

```json
{
"object": "realface.status",
"group_id": "legacy_rf_8137",
"group_id": "rf1_…",
"status": "pending_validation",
"asset_count": 0,
"ready_to_finalize": false
Expand All @@ -153,7 +157,9 @@ GET https://blockrun.ai/api/v1/realface/status?groupId=legacy_rf_…

When `status` transitions to `"active"` (and `ready_to_finalize: true`), the rights-holder has completed the H5 and you can move to step 4.

Poll every 3-5 seconds. Free but rate-limited (same bucket as wallet reconciliation, 120/hour/IP). A `groupId` that is missing or not of the form `legacy_rf_<digits>` is `400`; a well-formed id that does not exist is `404` (`{ "error": "Asset group not found: …" }`) — only a genuine upstream failure is `502`.
Poll every 3-5 seconds. Free but rate-limited (same bucket as wallet reconciliation, 120/hour/IP).

A **missing** `groupId` is `400`. Anything else that is not a handle this service issued — malformed, tampered with, or for a group that does not exist — is `404` (`{ "error": "Unknown group", "message": "Pass the group_id returned by POST /api/v1/realface/init." }`). The two cases are deliberately not distinguished: a different answer for a real group than for an absent one would confirm which groups exist. Only a genuine upstream failure is `502`.
:::

:::step{title="Finalize (PAID, $0.011 USDC)"}
Expand All @@ -168,7 +174,7 @@ POST https://blockrun.ai/api/v1/realface/enroll
{
"name": "Spokesperson — Q3 campaign",
"image_url": "https://example.com/person.jpg",
"group_id": "legacy_rf_8137"
"group_id": "rf1_…"
}
```

Expand Down Expand Up @@ -201,7 +207,7 @@ If settlement itself fails after a successful enrollment, BlockRun absorbs the c
{
"object": "realface",
"asset_id": "ta_f85b20b9394e47be9502d819bee7929c",
"group_id": "legacy_rf_8137",
"group_id": "rf1_…",
"byteplus_asset_id": "asset-20260525001905-…",
"name": "Spokesperson — Q3 campaign",
"image_url": "https://example.com/person.jpg",
Expand Down Expand Up @@ -254,7 +260,6 @@ Returns the wallet's enrolled RealFaces. Free, rate-limited (same 120/hour/IP bu
"realfaces": [
{
"assetId": "ta_f85b20b9394e47be9502d819bee7929c",
"groupId": "legacy_rf_8137",
"name": "Spokesperson — Q3 campaign",
"imageUrl": "https://example.com/person.jpg",
"createdAt": "2026-05-24T16:19:00.000Z",
Expand All @@ -272,9 +277,9 @@ The video playground reads this same list and shows it in the `real_face_asset_i

| Code | When | Did payment settle? |
|------|------|---------------------|
| 400 | Invalid request body, malformed `group_id`, bad image URL; on `/status`, missing/malformed `groupId` | – (pre-payment) |
| 400 | Invalid request body, bad image URL; on `/status`, a missing `groupId` | – (pre-payment) |
| 402 | Payment Required (first probe), or payment verification failed with `code` `PAYMENT_INVALID` / `PAYMENT_UNFUNDED` / `PAYMENT_BLOCKHASH_STALE` / `PAYMENT_REPLAY` | – |
| 404 | `/status`: `groupId` does not exist upstream | – |
| 404 | `group_id` is not a handle this service issued, or the group no longer exists — one answer for both, so group existence stays unreadable | – |
| 425 | `group_id` is in `pending_validation` — the rights-holder hasn't completed the H5 yet | **No** |
| 422 | Image rejected by the face service, or face-match failed — uploaded photo doesn't match the live H5 face | **No** |
| 429 | Rate limit on `/init` (10/hour/IP), `/status` or the listing (120/hour/IP) | – |
Expand Down
5 changes: 2 additions & 3 deletions docs/api-reference/virtual-portrait.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ If you're using `clawrouter` locally, this flow is fully automatic — just call
{
"object": "virtual_portrait",
"asset_id": "ta_abcdef1234567890",
"group_id": "tg_xyz9876543210",
"group_id": "legacy_rf_…",
"name": "My Spokesperson",
"image_url": "https://blockrun.ai/api/media/…",
"source_image_url": "https://example.com/character.jpg",
Expand All @@ -89,7 +89,7 @@ The settlement receipt is also returned in the `X-Payment-Response` / `PAYMENT-R
| Field | Description |
|-------|-------------|
| `asset_id` | The `ta_…` id to pass as `real_face_asset_id` on Seedance |
| `group_id` | Internal asset-group id — exposed for debugging / future delete operations |
| `group_id` | Internal asset-group id, returned for your own reference. No endpoint accepts it — enrollment mints its own group, so there is nothing to pass it back to. Not returned by the portraits listing |
| `image_url` | The BlockRun-hosted mirror of your image (so the listing thumbnail survives a dead source URL); falls back to the original URL if mirroring failed |
| `source_image_url` / `mirrored` | The URL you supplied, and whether the mirror succeeded |
| `usage.compatible_models` | Which BlockRun video models accept this asset id |
Expand Down Expand Up @@ -157,7 +157,6 @@ Returns the list of portraits the given wallet has enrolled. Free (rate-limited
"portraits": [
{
"assetId": "ta_abcdef1234567890",
"groupId": "tg_xyz9876543210",
"name": "My Spokesperson",
"imageUrl": "https://example.com/character.jpg",
"createdAt": "2026-05-22T14:32:11.000Z",
Expand Down
Loading