Guide
API reference
All paths below are relative to your API's base URL — the hosted default, or your own instance if you're self-hosting (see Self-hosted backend).
Authorization: Bearer pk_live_... — the header the official SDK's API client sends; mirror it from your own code. Response shapes marked illustrative further down aren't defined in the spec yet — confirm those against a running API. Everything else — the endpoint list, auth requirements, and the SignatureRecord shape — comes directly from the confirmed spec.Authentication
/auth/oauth/githubStart the GitHub OAuth flow.
Auth: —
/auth/oauth/googleStart the Google OAuth flow.
Auth: —
Projects & keys
/projectsCreate a new project. Returns its key pair — the secret key is only ever shown once.
Auth: Session (dashboard cookie)
Response (illustrative — confirm against real API)
{
"id": "proj_...",
"name": "My project",
"publicKey": "pk_live_...",
"secretKey": "sk_live_...",
"createdAt": "2026-07-18T09:12:00Z"
}/projects/:id/keys/rotateRotate a project's key pair. The old pair stops working immediately — no overlap window.
Auth: Session (dashboard cookie)
Response (illustrative — confirm against real API)
{
"publicKey": "pk_live_...",
"secretKey": "sk_live_..."
}Signatures
/signaturesSubmit a captured signature and its metadata.
Auth: Public key (pk_live_ / pk_test_)
Request body
{
"signature": "M10 10 L90 90 ...",
"location": null,
"deviceData": {
"userAgent": "...",
"inputType": "touch",
"pressureSupported": true
},
"siteUrl": "https://example.com/agreement",
"pageName": "agreement",
"createdBy": "signer@example.com"
}Response
{
"id": "sig_...",
"date": "2026-07-18T09:14:22Z",
"projectId": "proj_...",
"signature": "M10 10 L90 90 ...",
"location": null,
"deviceData": { "userAgent": "...", "inputType": "touch", "pressureSupported": true },
"siteUrl": "https://example.com/agreement",
"pageName": "agreement",
"createdBy": "signer@example.com"
}/signatures/:idRetrieve a single signature record by ID.
Auth: Secret key (sk_live_ / sk_test_)
Response
/* full SignatureRecord — see Data model below *//signatures?projectId=List signatures for a project, paginated.
Auth: Secret key (sk_live_ / sk_test_)
Response (illustrative — confirm against real API)
{
"data": [ /* SignatureRecord[] */ ],
"nextCursor": "..."
}/signatures/:idPermanently delete a record — used for right-to-erasure requests.
Auth: Secret key (sk_live_ / sk_test_)
Response (illustrative — confirm against real API)
{ "deleted": true }Data model: SignatureRecord
The confirmed shape from the technical spec — server-assigned fields are never accepted from the client on write.
interface SignatureRecord {
id: string; // UUID, server-assigned
signature: string; // SVG path data or base64 PNG
date: string; // ISO 8601, server-assigned — not client-trusted
location?: {
lat: number;
lng: number;
accuracy?: number;
} | null; // null unless the signer opts in
deviceData: {
userAgent: string;
inputType: 'touch' | 'pen' | 'mouse';
pressureSupported: boolean;
};
siteUrl: string;
pageName: string;
projectId: string; // inferred from the public key, not client-supplied
createdBy: string; // account email
}Errors
Standard HTTP status codes apply (400 for malformed requests, 401/403 for auth failures, 404 for missing records). The exact error body shape isn't finalized in the spec yet — check the real response once the API is running rather than relying on this page for it.