e-Próspera

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.

View as Markdown

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?EndpointCredential and scope
The authenticated person's own documentsGET /api/v1/me/natural-person/documentsOAuth with eprospera:person.documents.read, or an Agent Key with agent:person.documents.read
An applicant onboarded by your Partner IntegrationGET /api/v1/partner/residency_applications/{id}/documentsPartner 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:

SignalWhat it establishesWhat it does not establish
templatePdfUrlA downloadable template for the agreement versionThe applicant's signature or an approved residency
Partner accepted: trueThe current application acceptance has not been invalidatedPayment, identity verification, approval, or PDF generation
A document's non-null fileUrlA generated file is available to downloadCurrent 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 situationInterpretation 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 nullNo current acceptance record is attached. Follow the parent application's next steps.
Partner accepted: true, residencyEffectiveDate: nullConsent exists, but no resulting residency is attached yet. Finish remaining payment, verification, and submission steps.
Partner accepted: false with invalidatedAtAcceptance 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 fileGeneration may still be processing. Retry the document read with backoff; report persistent gaps with the application ID.
Personal AOC is null, historical files existNo currently active residency was found. Do not label an old file as the active agreement.
Personal AOC exists but signed URL is nullNo 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

  1. Refresh the metadata with an authorized API request.
  2. Select a document by ID/slug and check that its fileUrl is non-null. For the active personal AOC, prefer agreementOfCoexistence.signedDocumentUrl.
  3. 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.
  4. Record the document ID, slug, version, and retrieval time if your workflow needs an audit trail. Treat names as display labels; slug, version, and fileUrl may 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 statusCheck or action
401Confirm 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.
403Confirm the endpoint's required scope. Adding a scope to configuration does not modify an already-issued token or Partner Key.
404 on personal documentsNo natural-person record exists for the authenticated user. This differs from an existing person with an empty document list.
404 on applicant documentsCheck the application UUID and owning integration. An inaccessible application is deliberately indistinguishable from an unknown one.
429Honor Retry-After, then retry with backoff.
500 or network timeoutRetry 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 404 for 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 429 with backoff.
  • Check applicant status through the parent application; do not infer approval, identity verification, tax compliance, or renewal completion from document availability.

On this page