# Personal and applicant documents (/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](/entity-filings) and the
[entity documents endpoint](/reference/get-legal-entities-id-documents).

## Choose the right credential [#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](/oauth-overview). 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](/agent-keys). 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](/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 [#read-a-persons-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.

```bash
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](/testing-in-staging) for the hostname transition and OAuth
discovery instructions. A successful response is `200`:

```json
{
  "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](/reference/oauth-get-natural-person-documents)
for the complete field contract.

## Read your partner's applicant documents [#read-your-partners-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`:

```bash
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:

```json
{
  "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](/partner-keys) covers applicant consent and submission; the
[applicant documents reference](/reference/get-residency-applications-id-documents)
defines the response fields.

## Acceptance, templates, and signed PDFs [#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`:

```bash
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](/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 [#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. &#x2A;*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 [#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`:

```json
{ "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 [#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.
