Skip to content

Commit 840867d

Browse files
author
1bcMax
committed
Merge pull request #97 from BlockRunAI/docs/realface-documented-the-pre-seal-contract
docs(realface): the published contract described the pre-seal API
2 parents 20cfd0b + f322083 commit 840867d

2 files changed

Lines changed: 19 additions & 15 deletions

File tree

‎docs/api-reference/realface.md‎

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ You can use the web UI at [blockrun.ai/studio/realface](https://blockrun.ai/stud
2626
```
2727
[1] POST /v1/realface/init — FREE, rate-limited
2828
body: { "name": "..." }
29-
→ { group_id: "legacy_rf_…",
29+
→ { group_id: "rf1_…",
3030
h5_link: "https://kyc.byteintl.com/?...",
3131
expires_in_seconds: 120 }
3232
@@ -35,7 +35,7 @@ You can use the web UI at [blockrun.ai/studio/realface](https://blockrun.ai/stud
3535
record a 2-4 second video doing two prompted actions (nod, blink).
3636
NO login, NO ID upload, NO personal info.
3737
38-
[3] GET /v1/realface/status?groupId=legacy_rf_… — poll every 3-5s
38+
[3] GET /v1/realface/status?groupId=rf1_… — poll every 3-5s
3939
→ { status: "pending_validation", ready_to_finalize: false }
4040
→ ... (after H5 completes)
4141
→ { status: "active", ready_to_finalize: true }
@@ -67,21 +67,25 @@ POST https://blockrun.ai/api/v1/realface/init
6767
| Parameter | Type | Required | Description |
6868
|-----------|------|----------|-------------|
6969
| `name` | string | Yes | Display name for your reference (1–64 chars). Stored upstream + in your list |
70-
| `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 |
70+
| `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 |
7171

7272
### Response
7373

7474
```json
7575
{
7676
"object": "realface.init",
77-
"group_id": "legacy_rf_8137",
77+
"group_id": "rf1_…",
7878
"h5_link": "https://kyc.byteintl.com/?accessKeyId=...&sessionToken=...&configId=...",
7979
"status": "pending_validation",
8080
"expires_in_seconds": 120,
8181
"next_steps": { ... }
8282
}
8383
```
8484

85+
:::note{title="group_id is an opaque handle"}
86+
`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.
87+
:::
88+
8589
### Rate limiting
8690

8791
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`.
@@ -136,15 +140,15 @@ The H5 link works in any modern browser with a webcam. The rights-holder can ope
136140
:::step{title="Poll for completion (FREE)"}
137141

138142
```
139-
GET https://blockrun.ai/api/v1/realface/status?groupId=legacy_rf_…
143+
GET https://blockrun.ai/api/v1/realface/status?groupId=rf1_…
140144
```
141145

142146
### Response
143147

144148
```json
145149
{
146150
"object": "realface.status",
147-
"group_id": "legacy_rf_8137",
151+
"group_id": "rf1_…",
148152
"status": "pending_validation",
149153
"asset_count": 0,
150154
"ready_to_finalize": false
@@ -153,7 +157,9 @@ GET https://blockrun.ai/api/v1/realface/status?groupId=legacy_rf_…
153157

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

156-
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`.
160+
Poll every 3-5 seconds. Free but rate-limited (same bucket as wallet reconciliation, 120/hour/IP).
161+
162+
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`.
157163
:::
158164

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

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

273278
| Code | When | Did payment settle? |
274279
|------|------|---------------------|
275-
| 400 | Invalid request body, malformed `group_id`, bad image URL; on `/status`, missing/malformed `groupId` | – (pre-payment) |
280+
| 400 | Invalid request body, bad image URL; on `/status`, a missing `groupId` | – (pre-payment) |
276281
| 402 | Payment Required (first probe), or payment verification failed with `code` `PAYMENT_INVALID` / `PAYMENT_UNFUNDED` / `PAYMENT_BLOCKHASH_STALE` / `PAYMENT_REPLAY` | – |
277-
| 404 | `/status`: `groupId` does not exist upstream | – |
282+
| 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 | – |
278283
| 425 | `group_id` is in `pending_validation` — the rights-holder hasn't completed the H5 yet | **No** |
279284
| 422 | Image rejected by the face service, or face-match failed — uploaded photo doesn't match the live H5 face | **No** |
280285
| 429 | Rate limit on `/init` (10/hour/IP), `/status` or the listing (120/hour/IP) | – |

‎docs/api-reference/virtual-portrait.md‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ If you're using `clawrouter` locally, this flow is fully automatic — just call
6565
{
6666
"object": "virtual_portrait",
6767
"asset_id": "ta_abcdef1234567890",
68-
"group_id": "tg_xyz9876543210",
68+
"group_id": "legacy_rf_…",
6969
"name": "My Spokesperson",
7070
"image_url": "https://blockrun.ai/api/media/…",
7171
"source_image_url": "https://example.com/character.jpg",
@@ -89,7 +89,7 @@ The settlement receipt is also returned in the `X-Payment-Response` / `PAYMENT-R
8989
| Field | Description |
9090
|-------|-------------|
9191
| `asset_id` | The `ta_…` id to pass as `real_face_asset_id` on Seedance |
92-
| `group_id` | Internal asset-group id — exposed for debugging / future delete operations |
92+
| `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 |
9393
| `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 |
9494
| `source_image_url` / `mirrored` | The URL you supplied, and whether the mirror succeeded |
9595
| `usage.compatible_models` | Which BlockRun video models accept this asset id |
@@ -157,7 +157,6 @@ Returns the list of portraits the given wallet has enrolled. Free (rate-limited
157157
"portraits": [
158158
{
159159
"assetId": "ta_abcdef1234567890",
160-
"groupId": "tg_xyz9876543210",
161160
"name": "My Spokesperson",
162161
"imageUrl": "https://example.com/character.jpg",
163162
"createdAt": "2026-05-22T14:32:11.000Z",

0 commit comments

Comments
 (0)