Security profile
How the partner API authenticates each call and signs each webhook. The values below are generated from the code the API runs on. A section marked “At launch” describes what takes effect when the partner security platform opens; everything else is in effect now.
API keys
Send a key as Authorization: Bearer <key>. The quickstart shows a first call.
v2 keys At launch
sa_live_orsa_test_, then 30 base62 characters, then a 6-character base62 CRC-32 checksum: 44 characters in all. The checksum lets a mistyped key be refused before any lookup; it proves nothing about a key's authenticity.- A key holds only the permissions named on it:
referrals:write,referrals:read,referrals.contact:read,reporting:read,plans:read,plans:write,members:activation-link. - After you roll a key, the old one keeps working for at most 7 days, and never past its own expiry. A key neither used nor created in 90 days is flagged idle.
IP allowlists At launch
A key's allowlist holds at most 20 entries. The widest an entry may be is an IPv4 /16 or an IPv6 /32, and all of a key's entries together cover at most 65,536 IPv4 addresses and 2^96 IPv6 addresses.
Legacy keys
sa_gap_ keys (sa_gap_test_ for test) keep working until they're revoked or expire. At launch, an institution that requires signed requests refuses them, and a LIVE key's referral create waits for the institution's Administrator of Record to be verified.
Signed requests At launch
Instead of a key, an institution can register its own public key and sign each request. The signature follows RFC 9421 (HTTP Message Signatures) and RFC 9530 (Content-Digest).
- Algorithms:
ed25519orecdsa-p256-sha256. A signature is 64 bytes. - Signature label
sa, taggap-v2. Methods: GET, HEAD, POST, PATCH. No other method is signed, and a signed request carries no Authorization header. - Covered components, in order. POST and PATCH:
"@method" "@target-uri" "content-digest" "idempotency-key" "x-sa-environment". GET and HEAD:"@method" "@target-uri" "x-sa-environment", or"@method" "@target-uri" "idempotency-key" "x-sa-environment"when an Idempotency-Key is sent. - Content-Digest: sha-256, on POST and PATCH.
- Window:
createdat most 300 seconds old and 30 seconds ahead. - Nonce: 16 to 128 characters from
[A-Za-z0-9_-]. Each nonce is single-use for its credential, held until at least 331 seconds aftercreated. X-SA-Environment:TESTorPRODUCTION. Idempotency-Key: 1 to 255 visible ASCII characters (! to ~), required on POST and PATCH.- After a signed credential is replaced, the old one keeps working for at most 30 days, and never past its own expiry.
Webhooks
Signature
X-SecondAppraisal-Signature: t=<unix seconds>,v1=<hex>: HMAC-SHA256 over <t>.<raw body>. Verifying webhooks has the full steps and code.
Standard Webhooks headers At launch
webhook-id, webhook-timestamp, webhook-signature, sent to an endpoint with a Standard Webhooks secret.
Signing secrets
whsec_gap_: the HMAC key is the secret's text.- At launch
whsec_: a Standard Webhooks secret of 24 to 64 bytes. The HMAC key is the base64-decoded bytes after the prefix.
Secret rotation At launch
After a rotation, X-SecondAppraisal-Signature stays signed with the previous secret for 24 hours, unless you choose a shorter overlap or promote the new secret sooner, and then switches to the new one. An overlap is at most 168 hours. During an overlap, webhook-signature carries a signature from each Standard Webhooks secret in force.
Retention At launch
- The events feed lists the last 30 days of events; older events are deleted.
- 30 days after a delivery is created, a delivered or exhausted delivery's payload is replaced by a tombstone that keeps its SHA-256.
- Each record of a read of partner data is deleted after 395 days.
- An institution under a retention hold keeps its records until the hold is lifted.
These periods may change before launch.