Requesting documents
You start every flow by asking a subject for one or more documents, for a stated purpose.
POST /partner/v1/requests
Scope: requests:write
curl -X POST https://locke-api.trylockey.workers.dev/partner/v1/requests \
-H "Authorization: Bearer $LOCKEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": { "email": "applicant@example.com" },
"purpose": "employment_verification",
"reference": "candidate-4821",
"message": "Please share the documents below to complete onboarding.",
"items": [
{ "classification": "passport", "label": "Passport", "required": true },
{ "classification": "employment_letter", "label": "Prior employment", "required": false }
],
"constraints": { "maxViews": 5, "expiresAt": 1767225600000 }
}'Body fields
| Field | Type | Notes |
|---|---|---|
subject | { email? , phone? } | Exactly one of email / phone. |
purpose | enum | university_admission, employment_verification, property_rental, visa_application, identity_verification, custom. |
customPurpose | string ≤120 | Required when purpose = "custom". |
message | string ≤1000 | Optional note shown to the subject. |
reference | string ≤120 | Your own tag (e.g. ATS candidate id) — echoed back and filterable. |
items | array 1–10 | The documents you're asking for. |
items[].classification | enum? | Omit to accept any document. See list below. |
items[].label | string ≤120? | Human label for the ask. |
items[].required | boolean | Default true. |
constraints.maxViews | 1–1000? | View cap applied to the resulting grant. |
constraints.expiresAt | epoch ms? | Grant expiry applied at fulfillment. |
expiresAt | epoch ms? | The request itself lapses if unanswered by then. |
Classifications
passport, national_id, visa, degree, certificate, employment_letter, financial_document, insurance, contract, other.
High-sensitivity classes
Some classes (currently national_id) always re-prompt the subject for consent and, on live keys, require your org to be at the elevated verification tier. Otherwise:
403 { "error": "high_sensitivity_requires_elevated", "message": "…" }You can exercise these freely in sandbox before you're verified.
The response is always uniform
201 { "requestId": "…", "status": "pending" }Privacy guarantee — no existence oracle
The response, timing, and any side effects are identical for a known vs. unknown contact. Lockey stores only a hash of the subject's contact; delivery and audit happen after the response is returned. You cannot use this endpoint to test whether someone has a Lockey account.
Idempotency
There is no dedicated idempotency key. Use a unique reference per logical request, and check for an existing one (via the list endpoint) before retrying — so network retries don't create duplicate requests.
Next: Tracking requests →