Verify Signature

GET /api/v1/approvals/:id/verify -- cryptographically verify a signed approval decision. No authentication required.

Key Concepts

The verification endpoint is public -- no API key or authentication is required. This is by design: anyone should be able to independently verify that an approval decision is authentic, without needing a relationship with SignedApproval.

The endpoint performs the Ed25519 signature verification server-side and returns the result. It also returns the signature, payload, and public key so you can perform offline verification yourself.

Endpoint

text
GET https://signedapproval.net/api/v1/approvals/:id/verify
# No Authorization header needed

Response (Valid Signature)

JSON
{
  "valid": true,
  "decision": "approved",
  "method": "passkey",
  "verified_at": "2026-03-23T14:10:00.000Z",
  "public_key": "MCowBQYDK2VwAyEAbK9G3mMr...",
  "signature": "Wm9tSW1hZ2luYXJ5U2lnbmF0...",
  "payload": {
    "v": 1,
    "rid": "req_abc123def456",
    "did": "dec_xyz789abc012",
    "approver": "a1b2c3d4e5f6g7h8",
    "action": "9i8j7k6l5m4n3o2p",
    "decision": "approved",
    "method": "passkey",
    "ts": 1709000550,
    "exp": 1709004150,
    "nonce": "abcdef1234567890abcdef1234567890"
  }
}

Response (Request Not Yet Decided)

JSON
{
  "valid": false,
  "error": "No decision has been made yet",
  "status": "pending"
}

Response (Request Not Found)

JSON
{
  "valid": false,
  "error": "Approval request not found"
}

Example Usage

bash
# Verify from any system -- no API key needed
curl https://signedapproval.net/api/v1/approvals/req_abc123def456/verify
javascript
// Verify in your application
async function verifyApproval(requestId: string) {
  const res = await fetch(
    `https://signedapproval.net/api/v1/approvals/${requestId}/verify`
  );
  const data = await res.json();

  if (!data.valid) {
    throw new Error(`Approval verification failed: ${data.error}`);
  }

  console.log(`Approved via ${data.method} at ${data.verified_at}`);
  return data;
}

Audit Trail

Each verification attempt is logged in signedapproval_validationswith the verifier's IP address, timestamp, and result. This audit log is visible in the dashboard and through log sinks.

Note
The response includes everything needed for offline verification: the public_key, signature, and payload. Cache these values if you need to verify the same decision multiple times without making API calls.
Tip
Rate limit for verification is generous (300 requests/minute per IP) since it is a public endpoint. However, for high-volume verification, cache the result or perform offline verification with the returned public key.