Public API
Generated from the service OpenAPI contract. Only operations marked x-bv-audience: cli are included. Run
task docs:generateafter changing the public API contract.
Base URL: https://api.butverify.dev
Auth: Most endpoints use Authorization: Bearer <butverify installation token>. POST /v1/auth/login uses a GitHub user token and returns the butverify token.
POST /v1/auth/login
Exchange a GitHub user token for a butverify installation token.
- Stability:
stable - Auth: Bearer GitHub user token
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | LoginResponse | Login succeeded. |
401 | ErrorEnvelope | GitHub token missing, invalid, or no matching butverify installation exists. |
429 | - | Login rate limit exceeded. |
GET /v1/auth/whoami
Resolve the caller’s tenant from the bearer token.
- Stability:
stable - Auth: Bearer installation token
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | WhoamiResponse | Resolved tenant. |
401 | ErrorEnvelope | Token missing or invalid. |
426 | - |
GET /v1/sites
List sites for the authenticated tenant.
- Stability:
stable - Auth: Bearer installation token
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | ListSitesResponse | Site list. |
POST /v1/sites
Provision a new site (or idempotent retry).
- Stability:
stable - Auth: Bearer installation token
Request body:
- Schema:
CreateSiteRequest - Required: yes
Responses:
| status | schema | description |
|---|---|---|
200 | CreateSiteResponse | Idempotent retry — existing site returned. |
201 | CreateSiteResponse | New site created. |
402 | ErrorEnvelope | Quota exceeded or unpaid invoice. |
429 | - | Rate limit exceeded; carries Retry-After header. |
GET /v1/sites/{site_id}
Get a single site’s metadata.
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | Site | Site found. |
404 | - | No site with that ID owned by the authenticated tenant. |
DELETE /v1/sites/{site_id}
Soft-delete a site (status → expired).
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | DeleteSiteResponse | Site soft-deleted (idempotent on already-expired). |
GET /v1/sites/{site_id}/files
List files in the site (parsed from the manifest).
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | FilesListResponse | File list. |
GET /v1/sites/{site_id}/files/{file_path}
Stream a single file from the site.
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string | |
file_path | path | yes | string | Slash-separated path within the site (no ../, no leading slash). |
Range | header | no | string | RFC 7233 single byte-range (e.g. bytes=0-1023). Server returns 206 on hit. |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | - | Full body. |
206 | - | Partial body (Range hit). |
404 | - | File not found in this site. |
POST /v1/sites/{site_id}/finalize
Finalize a push — server untars staging, computes manifest, transitions to active.
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
- Schema:
FinalizeRequest - Required: yes
Responses:
| status | schema | description |
|---|---|---|
200 | FinalizeResponse | Finalize succeeded (or idempotent ack on already-active site). |
409 | - | Conflicting upload_id or manifest_sha. |
POST /v1/sites/{site_id}/heartbeat
Heartbeat from a long-running CLI push (E7 / S-6).
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
- Schema:
HeartbeatRequest - Required: yes
Responses:
| status | schema | description |
|---|---|---|
200 | HeartbeatResponse | Heartbeat recorded. |
GET /v1/sites/{site_id}/manifest
Stream the site’s manifest.json.
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | SiteManifest | Manifest body (application/json). |
409 | - | Site has no manifest yet (still creating/uploading). |
POST /v1/sites/{site_id}/pin
Pin an active site (paid plan only; clears expires_at).
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | PinResponse | Pinned (idempotent on already-pinned). |
402 | - | Free tier — pinning requires upgrade. |
409 | - | Site is not in active state. |
POST /v1/sites/{site_id}/unpin
Unpin a site (re-stamps default TTL).
- Stability:
stable - Auth: Bearer installation token
Parameters:
| name | in | required | schema | description |
|---|---|---|---|---|
site_id | path | yes | string |
Request body:
None.
Responses:
| status | schema | description |
|---|---|---|
200 | PinResponse | Unpinned (idempotent on already-active). |
409 | - | Site is not in pinned state, or state changed under us. |