API reference
Base URL: https://api.pryvc.com/v1. All responses share one envelope:
{ "ok": true, "data": { … }, "request_id": "…" }{ "ok": false, "error": { "code": "…", "message": "…" }, "request_id": "…" }Error messages never contain personal data. Include the request_id in support requests.
Authentication
Section titled “Authentication”| Scheme | Used by | How |
|---|---|---|
| API key | Business server-side | Authorization: Bearer sk_live_… (create in the portal; shown once) |
| Session cookie | Portals | Set by the auth endpoints; SameSite=Lax, httpOnly |
| PKCE code | SDK redemption | No credential — the single-use code is the proof |
API keys are rate-limited to 120 requests/min (429 + Retry-After). Past-due subscriptions
get read-only access; suspended businesses get 402.
Share protocol
Section titled “Share protocol”| Endpoint | Auth | Description |
|---|---|---|
GET /authorize |
public | Validate authorize params for the consent UI |
POST /share/consent |
consumer session | Create a share + mint a single-use code |
POST /share/redeem |
PKCE | Exchange {code, code_verifier, client_id} for the field payload — exactly once |
POST /share/sandbox-consent |
public (sandbox client only) | Popup-free consent for testing |
POST /shares/:id/revoke |
consumer session | Revoke + open a cease-contact notice |
POST /shares/:id/cease-ack |
API key | Acknowledge a cease-contact notice |
POST /me/shares/:id/renew |
consumer session | Re-consent; new share linked to the old |
Redeem errors
Section titled “Redeem errors”code_invalid · code_expired (60s TTL) · code_used (replay) · pkce_mismatch ·
origin_mismatch · share_inactive
Business API
Section titled “Business API”| Endpoint | Description |
|---|---|
GET /shares?status= |
Your shares (filterable; max 200) |
GET /shares/:id |
Full share detail incl. fingerprint |
GET /events?cursor=&limit= |
Event ledger, monotonic seq cursor |
GET /consumers/:share_id/current |
Current values of in-scope fields for an active share |
POST /webhooks · GET /webhooks · DELETE /webhooks/:id |
Endpoint management (portal session) |
POST /webhooks/:id/test |
Signed test delivery |
There is intentionally no bulk export and no cross-share access: every decryption path is scoped to one active share you own.
Consumer API (session)
Section titled “Consumer API (session)”| Endpoint | Description |
|---|---|
GET /me |
Profile + plan |
GET/PUT /me/fields |
Read / update canonical fields — updates fan out consumer.updated.* |
GET /me/shares |
All shares with business names + cease status |
GET /me/audit |
Hash-chained audit history |
GET /me/export |
Full DSAR export |
DELETE /me |
Account deletion (revokes actives, erases fields) |
POST /me/sever/:share_id |
Revoke + cease notice |
POST /me/removals · GET /me/removals |
White Glove removal requests |
GET /me/removals/:id/affidavit |
Completed affidavit PDF |
Billing
Section titled “Billing”| Endpoint | Description |
|---|---|
GET /billing/checkout?plan=business|white_glove |
Redirects to Stripe checkout bound to your account |
POST /webhooks/stripe |
Stripe entitlement sync (signature-verified) |
Health
Section titled “Health”GET /health — checks database, KV, and crypto context.
Certified consent (Enterprise)
Section titled “Certified consent (Enterprise)”Accountless consent capture (POST /v1/consent), public certificate verification
(GET /v1/certs/:id/verify), and the API-key certificate list/detail endpoints are
documented on the certified consent page.
Full endpoint list
Section titled “Full endpoint list”Every endpoint of the protocol surface, generated from the published description. Portal, admin, and consumer-account endpoints are deliberately excluded — they are operator concerns and may change without notice.
| Endpoint | Auth | What it does |
|---|---|---|
GET /v1/authorize |
public | Begin a grant authorization |
GET /v1/certs/{certId}/evidence-pack |
API key | Export a portable evidence pack |
GET /v1/certs/{certId}/verify |
public | Verify a certificate (public) |
GET /v1/certs/{certId} |
API key | Certificate detail |
GET /v1/certs |
API key | List certificates |
GET /v1/consumers/{shareId}/current |
API key | Current values for a grant |
GET /v1/events |
API key | Outbound event feed |
GET /v1/shares/{id} |
API key | Grant detail |
GET /v1/shares |
API key | List grants |
POST /v1/certs/{certId}/opt-out/confirm |
public | Confirm withdrawal |
POST /v1/certs/{certId}/opt-out/request |
public | Request a code to withdraw consent |
POST /v1/consent |
public | Issue a consent certificate |
POST /v1/share/consent |
public | Approve a grant |
POST /v1/share/redeem |
public | Redeem an authorization code |
POST /v1/shares/{id}/cease-ack |
API key | Acknowledge a cease obligation |
POST /v1/shares/{id}/revoke |
public | Revoke a grant |
The machine-readable version is sp1-hub.openapi.json (OpenAPI 3.1), with an explainer at shareprotocol.org/hub-api. It is compared against the running route table on every build and fails in both directions — a documented path that no longer exists, or a hub path added without description — so it cannot quietly drift from the API you are calling.
Withdrawal endpoints
Section titled “Withdrawal endpoints”A certificate subject has no account, so these are public and take an emailed code as proof of control.
POST /v1/certs/{certId}/opt-out/request — body { "email": "..." }. Always returns the
same response whether or not the address is on the certificate. Certificate ids are public,
so any difference would let a holder probe for the subject’s address.
POST /v1/certs/{certId}/opt-out/confirm — body { "email": "...", "code": "123456" }.
On success returns { "revoked": true, "cease_by": "..." }. A wrong address and a wrong code
return the same failure, for the same reason.