Personal and applicant documents
Retrieve a person's own documents or your integration's applicant agreements, distinguish acceptance from signed PDFs, and handle missing or delayed documents.
These endpoints return document metadata and download URLs. They do not accept signatures, approve residency, or replace applicant consent. For company certificates and filings, use Amendments and certificates and the entity documents endpoint.
Choose the right credential
| Whose documents? | Endpoint | Credential and scope |
|---|---|---|
| The authenticated person's own documents | GET /api/v1/me/natural-person/documents | OAuth with eprospera:person.documents.read, or an Agent Key with agent:person.documents.read |
| An applicant onboarded by your Partner Integration | GET /api/v1/partner/residency_applications/{id}/documents | Partner Key with partner:person.application.read |
Standard Keys (sk-) cannot call either endpoint. Partner Keys (pk-) cannot call the
personal endpoint; OAuth and Agent Keys cannot call the partner endpoint. There is no
arbitrary-person lookup: adding a userId, email, or RPN does not change whose documents
the personal endpoint returns.
For OAuth, provision the documents scope on your client and request it through the authorization-code flow. Existing tokens do not gain a scope when you change your client configuration: obtain consent and a new token. For Agent Keys, the owner grants the scope in Developer → Agents. Read access does not require the Manifestation of Will required for Agent Key writes.
Partner Keys must be issued with the read scope by e-Próspera; see
Partner onboarding. The application must belong to that key's
integration. Use the application UUID returned by your create or list request, not the
person's RPN or a residency UUID. A different integration's application returns 404.
Read a person's own documents
Run requests from your backend. The examples contain fictional IDs, names, dates, and document URLs. Use your own staging credentials; production credentials are separate.
export BASE_URL='https://stg.portal.eprospera.com'
export ACCESS_TOKEN='<your-staging-oauth-token-or-agent-key>'
curl --fail-with-body -sS "$BASE_URL/api/v1/me/natural-person/documents" \
-H "Authorization: Bearer $ACCESS_TOKEN"See Testing in staging for the hostname transition and OAuth
discovery instructions. A successful response is 200:
{
"data": [
{
"id": "55555555-5555-4555-8555-555555555555",
"name": "Agreement of Coexistence",
"slug": "aoc_77777777-7777-4777-8777-777777777777",
"version": "1.0",
"fileUrl": "https://documents.example.test/signed-agreement.pdf",
"createdAt": "2026-09-17T14:03:00.000Z"
}
],
"agreementOfCoexistence": {
"aocId": "88888888-8888-4888-8888-888888888888",
"slug": "example-e-resident-aoc",
"version": "1.0",
"residencyType": "e-Resident",
"effectiveDate": "2026-09-17T14:00:00.000Z",
"terminationDate": null,
"templatePdfUrl": "https://documents.example.test/agreement-template.pdf",
"signedDocumentId": "55555555-5555-4555-8555-555555555555",
"signedDocumentUrl": "https://documents.example.test/signed-agreement.pdf"
}
}data contains the authenticated person's non-admin, non-hidden documents, newest first, including
historical documents. It is broader than the partner endpoint's agreement/policy subset.
There is no pagination or documented filter on either documents endpoint.
agreementOfCoexistence describes the most recent currently active residency. A
future residency does not qualify until its effective date. The object is null when no
residency is active, even if historical agreements remain in data.
Use signedDocumentUrl for the signed agreement for that active residency. It is matched
by the exact aoc_{residencyId} slug. An older agreement or a document merely named
“Agreement of Coexistence” is not substituted. The object can exist while
signedDocumentId and signedDocumentUrl are null. If the document row exists but its
file has not been attached, the ID can be populated while the URL is still null.
See the personal documents reference for the complete field contract.
Read your partner's applicant documents
Save the application ID when creating the applicant through the Partner API. You can also
retrieve your integration's applications with GET /api/v1/partner/residency_applications.
This read request requires no Idempotency-Key:
export BASE_URL='https://stg.portal.eprospera.com'
export PARTNER_KEY='<your-staging-partner-key>'
export APPLICATION_ID='44444444-4444-4444-8444-444444444444'
curl --fail-with-body -sS \
"$BASE_URL/api/v1/partner/residency_applications/$APPLICATION_ID/documents" \
-H "Authorization: Bearer $PARTNER_KEY"A successful response after approval and document generation looks like this:
{
"data": [
{
"id": "55555555-5555-4555-8555-555555555555",
"name": "Agreement of Coexistence",
"slug": "aoc_77777777-7777-4777-8777-777777777777",
"version": "1.0",
"fileUrl": "https://documents.example.test/signed-agreement.pdf",
"createdAt": "2026-09-17T14:03:00.000Z"
}
],
"agreementOfCoexistence": {
"aocId": "88888888-8888-4888-8888-888888888888",
"slug": "example-e-resident-aoc",
"version": "1.0",
"residencyType": "e-Resident",
"templatePdfUrl": "https://documents.example.test/agreement-template.pdf",
"accepted": true,
"acceptedAt": "2026-09-17T13:00:00.000Z",
"signerName": "Alex Example",
"invalidatedAt": null
},
"residencyEffectiveDate": "2026-09-17T14:00:00.000Z"
}The partner response uses the current acceptance record for this application, not the
person's latest active residency. It has no signedDocumentUrl property: find the signed
file in data. Only the AOC for the application's resulting residency is included, using
its exact aoc_{residencyId} slug. An AOC from another residency is excluded.
The other permitted slugs are terms, privacy_policy, background_check, and
civil_penalty. These are shared policy documents, not evidence that each policy was
signed again for this specific application. Not every response contains every slug.
Identity-verification artifacts, tax documents, unrelated uploads, and admin-only
or hidden documents are excluded. Classify by slug, not display name or array position.
The Partner Keys guide covers applicant consent and submission; the applicant documents reference defines the response fields.
Acceptance, templates, and signed PDFs
These are three different signals:
| Signal | What it establishes | What it does not establish |
|---|---|---|
templatePdfUrl | A downloadable template for the agreement version | The applicant's signature or an approved residency |
Partner accepted: true | The current application acceptance has not been invalidated | Payment, identity verification, approval, or PDF generation |
A document's non-null fileUrl | A generated file is available to download | Current acceptance validity, current residency status, or a successful renewal |
For a partner workflow, read the parent application for its status and nextSteps:
curl --fail-with-body -sS \
"$BASE_URL/api/v1/partner/residency_applications/$APPLICATION_ID" \
-H "Authorization: Bearer $PARTNER_KEY"Complete the hosted or embedded applicant steps described in Partner Keys.
Once the application is approved, fetch /documents until the required signed file is
available. Do not create a second application or collect a replacement signature just
because document generation has not finished.
| Response or situation | Interpretation and next action |
|---|---|
200, data: [] | A valid response, not an authorization failure. Check the parent application's progress before waiting for generation. |
| Partner AOC is null | No current acceptance record is attached. Follow the parent application's next steps. |
Partner accepted: true, residencyEffectiveDate: null | Consent exists, but no resulting residency is attached yet. Finish remaining payment, verification, and submission steps. |
Partner accepted: false with invalidatedAt | Acceptance was invalidated, for example after changing application data. Fetch the application again and complete its current consent step. An old file does not restore consent. |
| Approved application but no signed AOC file | Generation may still be processing. Retry the document read with backoff; report persistent gaps with the application ID. |
| Personal AOC is null, historical files exist | No currently active residency was found. Do not label an old file as the active agreement. |
| Personal AOC exists but signed URL is null | No downloadable file is matched to the active residency yet. Retry; if persistent, report the missing match instead of selecting an older or similarly named file. |
Documents hidden by an administrator are excluded from both endpoints, including the personal signed-AOC lookup. A missing file can therefore reflect a visibility decision, not only generation delay. Do not recreate the application or substitute a historical agreement; contact support if the expected document stays unavailable.
Download and store documents
- Refresh the metadata with an authorized API request.
- Select a document by ID/slug and check that its
fileUrlis non-null. For the active personal AOC, preferagreementOfCoexistence.signedDocumentUrl. - Fetch that URL as a separate request. Do not forward your API Bearer credential to the document host. These metadata routes return JSON, not PDF bytes.
- Record the document ID, slug, version, and retrieval time if your workflow needs an
audit trail. Treat names as display labels;
slug,version, andfileUrlmay be null.
No URL expiry interval or time-limited signed-download contract is promised by these endpoints. Revoking a key or OAuth grant prevents subsequent authorized API reads; do not assume it invalidates a previously copied file URL. Keep URLs and downloaded agreements out of public logs, analytics, and unauthenticated pages. Restrict your own stored copies to the correct customer.
If a file URL fails, fetch metadata again and try its current URL. A persistent broken link should be reported with the document and application IDs, without sending the document, credential, or full download URL in the report.
Errors, retries, and polling
Read the HTTP status first. Error bodies contain error; a machine-readable code is
not guaranteed. For example, an inaccessible partner application returns 404:
{ "error": "Residency application not found" }| HTTP status | Check or action |
|---|---|
401 | Confirm the environment, credential type, validity, and expiry. Refresh OAuth tokens when appropriate; replace/re-enable expired, revoked, or inactive partner access through the provisioning process. |
403 | Confirm the endpoint's required scope. Adding a scope to configuration does not modify an already-issued token or Partner Key. |
404 on personal documents | No natural-person record exists for the authenticated user. This differs from an existing person with an empty document list. |
404 on applicant documents | Check the application UUID and owning integration. An inaccessible application is deliberately indistinguishable from an unknown one. |
429 | Honor Retry-After, then retry with backoff. |
500 or network timeout | Retry the same GET with exponential backoff and jitter; reads do not create documents or repeat payment. |
Partner reads allow 120 requests/minute per key and 300/minute per integration, shared with other partner read endpoints. Avoid one rapid poller per document. Poll while a required document is pending, for example every 5–30 seconds with backoff, and stop once it is available. This interval is a client recommendation, not a generation-time guarantee. There is no outbound document-ready webhook in this release.
Integration acceptance checklist
- Verify OAuth and/or Agent Key access for the correct person, including a missing-scope failure and a revoked credential.
- Verify partner access to an owned application and
404for another integration's ID. - Handle acceptance before approval, an empty document list, and a null file URL without treating them as completed document delivery.
- Confirm that a signed AOC for a different residency is never shown as the requested agreement, and handle invalidated acceptance separately from existing files.
- Download the returned PDF without sending the API key to the file host. Stop polling
after completion and handle
429with backoff. - Check applicant status through the parent application; do not infer approval, identity verification, tax compliance, or renewal completion from document availability.
Amendments and certificates
Prepare entity amendments, complete representative signing and payment, track review, and retrieve certificates and applicant documents.
Testing in staging
Use separate staging accounts and credentials to test e-Próspera API, OAuth, and payments. Voucher API1234 covers every product; Stripe test card ACCT-000015.