API reference · Enrolment

Prove you hold the key

POST/v1/enrollments/{invitationId}/proof

Sends the proof of possession. Once accepted, the key waits for Anis staff to phone you, check its safety code and confirm it.

PermissionNone
AuthenticationEnrolment token
Anis’s answerSigned
Staff-set limits it counts towardNone
.NET SDKenrollment.ProveAsync(submitted, key)
  • A proof that does not verify, or comes more than about 30 minutes after the key submission, is not refused: the answer says proofState: "failed". Check for "accepted".
  • More than about 30 minutes after the key submission a proof can no longer succeed: do not prove again — ask Anis staff to restart the enrolment. After five failed proofs the next one is refused as invitation_invalid.
  • key_duplicate on the proof means the proof was already accepted (its answer was lost and the same proof was sent again). Read the status before anything else.

Parameters

NameInTypeNotes
invitationIdrequiredpathUUIDA UUID, lower-case with hyphens.

Request

Authorised with Authorization: Enrollment <token>; not signed.

Headers: Accept-Language (optional). The SDKs set all of them for you.

Body: EnrollmentProofRequest, as JSON.

FieldTypeNotes
keyIdrequiredUUIDThe key id from the key submission.
challengeGenerationrequiredintegerThe challenge generation you are answering.
signaturerequiredstringECDSA P-256/SHA-256 over the proof message, 64 bytes (not DER), base64url without padding.

Responses

StatusMeaningBody
200Success.EnrollmentStatus
401Refused: not authenticated.Problem
404Refused: not found, or not yours.Problem
409Refused: conflicts with the current state.Problem
422Refused: the request breaks a rule.Problem
429Refused: a limit was reached.Problem
503No decision: a dependency was unavailable.Problem

Every answer of this call is signed by Anis — success and every refusal. Require the signature and verify it before you act on the answer; an answer without one is a failure, never an answer (how).

Refusals

Every refusal of this call is a signed problem. Branch on its code; each links to what it means and what to do.

ErrorCodeStatus
Invitation invalidinvitation_invalid401
Not foundresource_not_found404
Validation failedvalidation_failed422
Challenge replacedchallenge_expired409
Invitation already usedkey_duplicate409
Rate limitedrate_limited429
Service unavailabledependency_unavailable503
Request timeoutrequest_timeout504
Internal errorinternal_error500

Types

EnrollmentProofRequest

FieldTypeNotes
keyIdrequiredUUIDThe key id from the key submission.
challengeGenerationrequiredintegerThe challenge generation you are answering.
signaturerequiredstringECDSA P-256/SHA-256 over the proof message, 64 bytes (not DER), base64url without padding.

EnrollmentStatus

FieldTypeNotes
keyIdUUIDYour key id.
challengeGenerationintegerThe current challenge generation.
proofStatestringpending, accepted or failed — a proof that did not verify or came too late. After five failed proofs the next one is refused as invitation_invalid: ask Anis staff to restart the enrolment.
approvalStatestringpending while Anis staff have not confirmed the key, approved once it is active, notApplicable otherwise.
statestringpendingInvitation, pendingProof, pendingApproval, active — the key signs requests — or unavailable (the key is being replaced by a newer one). A revoked, retired or expired key is not reported: the status read answers resource_not_found.
expiresAtstring (date-time)When the current enrolment step lapses: the invitation, while it is still open. Absent once the key is active or no longer available — the key’s own end date is keyExpiresAt.
keyExpiresAtstring (date-time)The date your active key stops working (absent until the key is active). Ask Anis staff for a replacement weeks before it: a key past its end date is refused as invalid_credentials on every call, including reveals of cards you already bought.