e-Próspera

Tax and legal-entity data

See which tax filings are due, review past returns, download tax documents, and access information about businesses you represent, with your permission.

View as Markdown

These APIs let an app show someone their tax records and information about businesses they represent. The person signs in and chooses what to share. For a business, they must select it and remain an active representative.

What each tax information API does

These four APIs help people keep track of VAT and annual income tax:

APIWhat it does for the user
Tax overviewShows which filing periods are open or overdue and their due dates. It also shows whether a recorded lump-sum tax election is active or expired. This is an overview of filing obligations, not a payment balance or proof that every tax obligation has been satisfied.
Filing historyLists returns already submitted, with the option to narrow the list by tax type and year. It helps someone find a past VAT or annual income-tax filing; unfinished drafts are not included.
Filing detailsOpens one submitted return to show its reported figures, calculated tax, submission date, linked invoice status, and available documents.
Download tax documentsDownloads an assessment PDF showing the tax calculation for a filed return. Annual income-tax filings also support a separate filed-return PDF; VAT currently provides the assessment PDF.

These APIs only show or download information. They do not prepare, change, submit, or pay a return. To prepare and submit an original quarterly VAT filing in US dollars, use the Quarterly VAT APIs, with the person's separate permission to file.

Available data

An authorized user can:

  • view personal tax obligations, including open and overdue periods;
  • list submitted income-tax and VAT filings;
  • inspect a submitted filing and its calculated amounts;
  • download an assessment or filed-return PDF;
  • list legal entities selected during OAuth consent;
  • read a selected entity's profile and available documents; and
  • perform the same read-only tax operations for a selected entity they still actively represent.

Tax summaries are calculated without creating draft statements. Use the HTTP walkthrough to connect your own app, or the official CLI to explore records from the terminal.

Access boundaries

DataRequired scopeAdditional checks
Personal tax recordseprospera:person.tax.readThe OAuth user can only request their own records.
Legal-entity profileeprospera:entity.readThe entity must be selected during consent.
Legal-entity documentseprospera:entity.documents.readThe entity must be selected during consent.
Personal documentseprospera:person.documents.readThe OAuth user can only request their own documents, such as the signed Agreement of Coexistence.
Legal-entity tax recordseprospera:entity.tax.readThe entity must be selected during consent and the user must remain an active representative.

Selecting an entity during consent does not permanently bypass membership checks. If the user stops representing that entity, subsequent requests stop returning its data.

Direct API endpoints

Use subject=personal for the authenticated user's records or subject=<entity-uuid> for a consented legal entity. Tax endpoints accept the matching personal or entity tax scope; having one does not grant the other.

Prepare your first request

Request an OAuth client through the Help Center chat and complete the OAuth authorization flow. Ask for personal tax read permission, business tax read permission, or both, according to what your app needs. For example, an app that reads selected businesses' tax records can request:

openid profile eprospera:entity.tax.read

Use the resulting access token, not an ID token, Standard Key, Agent Key, or Partner Key. The person must select the businesses during consent. An entity-read permission alone does not grant access to its taxes.

These terminal examples use curl with --fail-with-body support and jq. Start with a separately provisioned staging client:

export BASE_URL='https://stg.portal.eprospera.com'
export ACCESS_TOKEN='<your-staging-oauth-access-token>'
TAX_SUBJECT='personal'

To read business records instead, set TAX_SUBJECT to a business UUID returned by the tax overview or the consented entity list. The latter also requires eprospera:entity.read. Do not send an RPN as subject. Omitting subject from summary/list requests returns data for all taxpayers accessible through the token. Sending subject= with no value is invalid.

All IDs, names, dates, and amounts shown below are fictional. Replace them with your own authorized values. Stop on HTTP errors before using the response; --fail-with-body returns a nonzero exit code and keeps the error body visible.

Read the tax overview

Call tax summary to show outstanding filing periods without creating a draft:

TAX_SUMMARY="$(curl --fail-with-body -sS -G \
  "$BASE_URL/api/v1/me/tax/summary" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  --data-urlencode "subject=$TAX_SUBJECT")"
printf '%s\n' "$TAX_SUMMARY" | jq .

Example response for a person with an open VAT quarter:

{
  "data": {
    "subjects": [
      {
        "subject": {
          "type": "natural_person",
          "id": "33333333-3333-4333-8333-333333333333",
          "name": "Alex Example",
          "residentPermitNumber": "90123456789012"
        },
        "obligations": [
          {
            "type": "vat",
            "period": { "year": 2026, "quarter": 3 },
            "dueDate": "2026-10-15T23:59:59.999Z",
            "status": "open",
            "filingId": null
          }
        ],
        "lumpSumElections": []
      }
    ]
  }
}
  • Show the returned taxpayer name, type of tax, period, due date, and open or overdue status. Use the returned due date rather than calculating a deadline in your app; reviewed requirements can affect the result.
  • VAT uses quarter numbers 1–4. Annual income-tax periods use quarter: null.
  • An obligation's filingId may refer to an unfinished draft. The submitted-filing endpoint below will not return drafts. Use the separately authorized VAT draft workflow to work on an original USD VAT draft.
  • lumpSumElections shows recorded personal lump-sum tax elections. It is an empty list for businesses and when no personal election is recorded.
  • An empty obligations list means no open/overdue periods were returned. It is not a payment statement or a Certificate of Good Standing.

If you omit subject and get subjects: [], check which permissions and businesses were granted. An explicitly requested taxpayer outside that access returns 404.

List submitted filings

Call filing history to find completed returns:

TAX_TYPE='vat'
TAX_YEAR=2026
TAX_FILINGS="$(curl --fail-with-body -sS -G \
  "$BASE_URL/api/v1/me/tax/filings" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  --data-urlencode "subject=$TAX_SUBJECT" \
  --data-urlencode "type=$TAX_TYPE" \
  --data-urlencode "year=$TAX_YEAR" \
  --data-urlencode 'limit=20')"
printf '%s\n' "$TAX_FILINGS" | jq '{
  filings: [.data[] | {id, type, period, submittedAt}],
  nextCursor: .meta.nextCursor
}'

Example output from the jq selection after a return has been submitted:

{
  "filings": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "type": "vat",
      "period": { "year": 2026, "quarter": 3 },
      "submittedAt": "2026-10-04T18:00:00.000Z"
    }
  ],
  "nextCursor": null
}

The HTTP response contains full filing objects in data, with the same fields as filing details, plus meta.nextCursor. The example above only prints the fields needed for a history list. Results are newest first by submission date, with ID as the tie-breaker.

Query parameterHow to use it
subjectpersonal or a consented business UUID. Omit to include all accessible taxpayers.
typevat or income. Omit to include both.
yearThe filing's tax year, from 2020 through 9999. Omit for all years.
limitPage size, 1–100; defaults to 50.
cursorThe previous response's meta.nextCursor. Omit on the first request.

An empty data array with nextCursor: null means no submitted filings matched these filters. It does not tell you whether a draft exists or a return is due.

Fetch the next page

If meta.nextCursor is non-null, pass it back unchanged and URL-encoded. Keep the same subject, tax type, and year while paging. Do not decode it or use a filing ID as the cursor.

NEXT_CURSOR="$(printf '%s' "$TAX_FILINGS" | jq -r '.meta.nextCursor // empty')"
if [ -n "$NEXT_CURSOR" ]; then
  TAX_FILINGS="$(curl --fail-with-body -sS -G \
    "$BASE_URL/api/v1/me/tax/filings" \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    --data-urlencode "subject=$TAX_SUBJECT" \
    --data-urlencode "type=$TAX_TYPE" \
    --data-urlencode "year=$TAX_YEAR" \
    --data-urlencode 'limit=20' \
    --data-urlencode "cursor=$NEXT_CURSOR")"
  printf '%s\n' "$TAX_FILINGS" | jq .
fi

Repeat for each returned cursor until it is null. A malformed cursor returns 400 with error: "invalid_cursor"; restart from the first page if necessary.

Read a submitted filing

Let the person select an ID from filing history, then call filing details. Replace the fictional ID here with that selection:

FILING_ID='44444444-4444-4444-8444-444444444444'
TAX_FILING="$(curl --fail-with-body -sS \
  "$BASE_URL/api/v1/me/tax/filings/$FILING_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN")"
printf '%s\n' "$TAX_FILING" | jq .

Example 200 response for a submitted personal VAT return:

{
  "data": {
    "id": "44444444-4444-4444-8444-444444444444",
    "subject": {
      "type": "natural_person",
      "id": "33333333-3333-4333-8333-333333333333",
      "name": "Alex Example",
      "residentPermitNumber": "90123456789012"
    },
    "type": "vat",
    "period": { "year": 2026, "quarter": 3 },
    "submittedAt": "2026-10-04T18:00:00.000Z",
    "amended": false,
    "currency": "usd",
    "accountingMethod": "cash",
    "reported": { "grossIncome": "0", "taxCredit": "0", "taxWithheld": "0" },
    "usdEquivalent": null,
    "taxLiability": "0",
    "exchangeRate": null,
    "invoice": null,
    "availableDocuments": ["assessment"]
  }
}

reported holds the original figures in the filing's currency. Amounts are decimal strings, and a null figure means unavailable, not zero. BTC filings can also include frozen USD equivalents and exchange-rate information; do not replace those with today's rate. taxLiability is the USD liability recorded for the filing. amended identifies an amended return.

The linked invoice can be null, as in a zero-tax filing. Its status is useful context, but do not infer the user's total outstanding balance from this one return. This endpoint reads submitted returns only; use the VAT draft endpoint to track a filing still being prepared.

Download a tax document

Read availableDocuments on the selected filing and call download tax document:

DocumentAvailable forResult
assessmentSubmitted VAT and annual income-tax filingsNotice of assessment PDF.
returnSubmitted annual income-tax filingsFiled income-tax return PDF.

Download an assessment into a new private directory:

umask 077
DOWNLOAD_DIR="$(mktemp -d)"
curl --fail -sS \
  "$BASE_URL/api/v1/me/tax/filings/$FILING_ID/documents/assessment" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -o "$DOWNLOAD_DIR/assessment.pdf"

A successful response is binary PDF data with Content-Type: application/pdf and a download filename in Content-Disposition. It has no JSON data wrapper. The example uses --fail so an HTTP error body is not saved as a PDF. Check the exit status before opening the file, and keep downloaded tax documents private.

For a filing whose availableDocuments contains return, use the same command with /documents/return and a suitable output filename. VAT has no separate filed-return PDF through this endpoint.

Assessments accept ?history_years=1 through 5, defaulting to 1, to control the included assessment history. Do not send history_years for a return download; that combination returns 400.

Handle missing records and errors

Check HTTP status first. Error responses contain error; a data field is not present on every response. For example, an inaccessible submitted filing returns 404:

{ "error": "Tax filing not found" }
ResultWhat your app should do
200 with an empty listShow an empty state for the selected filters. Check the overview separately for outstanding periods.
400Fix the subject, filters, cursor, or document request. A VAT return download is unsupported.
401Refresh an expired access token when supported, or reconnect if it was revoked or refresh fails.
403Request the matching tax read permission and obtain consent. Entity profile access or VAT write access alone is insufficient.
404Check the ID, environment, consented business, and current representative role. A draft cannot be read through the submitted-filing endpoint.
500 or a connection failureRetry these read requests with backoff. Do not treat missing results as proof of a missing filing or no tax due.

For VAT write errors and recovery, follow the separate filing guide; interrupted writes need different handling.

Use the official CLI

Install the official CLI, then authorize it in a browser. For staging, select the environment before login and keep it selected for later commands:

export EPROSPERA_ENV=staging
export EPROSPERA_BASE_URL=https://stg.portal.eprospera.com
eprospera auth login --oauth

The browser consent page shows the requested permissions and lets the user select which legal entities to share. The CLI client has no embedded secret and requests only the published user and entity scopes.

List the entities available to the CLI, then replace the sample ENTITY_ID with a returned business ID before reading its details:

eprospera --json me legal-entities list
ENTITY_ID='11111111-1111-4111-8111-111111111111'
eprospera --json me legal-entities get "$ENTITY_ID"
eprospera --json me legal-entities documents "$ENTITY_ID"

Read personal tax information, selecting a returned FILING_ID before reading or downloading that filing:

eprospera --json tax status --subject personal
eprospera --json tax list --subject personal --type income --year 2025
FILING_ID='44444444-4444-4444-8444-444444444444'
eprospera --json tax get "$FILING_ID"
eprospera tax download "$FILING_ID" --document assessment

For entity taxes, use a consented business UUID and select a filing from that business's returned list before downloading:

eprospera --json tax status --subject "$ENTITY_ID"
eprospera --json tax list --subject "$ENTITY_ID" --type vat --year 2026
FILING_ID='22222222-2222-4222-8222-222222222222'
eprospera tax download "$FILING_ID" --document assessment --output vat-assessment.pdf

tax list returns an opaque cursor for the next page when more filings are available. Pass that value back with --cursor; do not parse or modify it.

Entity detail fields

Both API-key entity detail reads and consented OAuth entity detail reads return the same additional profile fields. OAuth still requires consent and current representation; API keys still require representation, with Agent Keys limited to API-incorporated entities.

FieldMeaning
idLegal-entity UUID used in API paths.
residentPermitNumber14-digit RPN, or null when unavailable.
jurisdictionOfFormationRecorded jurisdiction of formation.
formationDateRecorded formation date, formatted YYYY-MM-DD.
statusdissolved when dissolution has taken effect; otherwise active if residency is current, or inactive.
residencyStatusWhether a residency term is currently active.
residencyCurrent residency type, effective date, and termination date, or null.
registeredAgentCurrent agent's provider ID, name, attention line, website, RPN, term dates, and office/mailing addresses, or null.
registeredAddressCurrent registered agent's office address, or null.
principalOfficeAddressThe entity's separately recorded principal-office address.

Only terms that have started and have not terminated are returned. Missing registered-office data is not replaced with a principal-office or mailing address. The detail fields are additive; the entity-list endpoint remains a summary. This API does not expose a separate registrationNumber; use the UUID and RPN as distinct identifiers.

An active status is a residency/registration indicator, not proof of tax compliance or good standing. Use the Certificate of Good Standing workflow when a certificate is required.

Handling sensitive information

Tax amounts, filing history, assessments, returns, and some legal-entity documents are confidential financial information.

  • Do not place access tokens, refresh tokens, tax responses, or downloaded documents in source control or shared logs.
  • Treat JSON and human-readable terminal output as sensitive; shell redirection and CI log capture can persist it.
  • Tax PDFs are created with owner-only file permissions on supported platforms. The CLI refuses to overwrite an existing file unless --yes is supplied.
  • Use eprospera --yes auth logout to revoke the remote OAuth session and remove the locally stored credential.

The CLI stores credentials in the operating-system keychain when available. Its protected local-file fallback is intended for a single-user workstation, not a shared machine.

On this page