Skip to content
Back to Steward

Exports

An application can be exported in four formats. All four render the same underlying record, so a value that appears in the CSV appears in the JSON and the PDF too. The formats differ in presentation, not in content.

Format Endpoint Content type Use it for
CSV GET /applications/{id}/export/csv text/csv Loading into a spreadsheet or a data pipeline
JSON GET /applications/{id}/export/json application/json Machine consumption where you want the full structure
PDF GET /applications/{id}/export/pdf application/pdf A human-readable record to file or send to a regulator
XML GET /applications/{id}/export/xml application/xml Regulatory submission, including CRS

Every response is a file download. The bytes come back directly with a Content-Disposition attachment filename, not a link to fetch later.

Terminal window
curl -L "https://api.getsteward.ai/api/v1/applications/{id}/export/pdf?risk=true&screening=true" \
-H "Authorization: Bearer stw_live_your_api_key_here" \
-o application.pdf

The application’s own data (its profile, fields, and verification outcomes) is always included. Four optional sections are off by default and shared across all four formats:

Parameter Adds
screening Screening hits and their review decisions
risk The risk score and its per-factor breakdown
documents The document list, with validation results and file links
audit The application’s audit trail

Each accepts true / false (and 1 / 0). They are validated strictly: an unrecognised value is rejected with a 400 rather than being quietly treated as false, so a typo fails loudly instead of silently producing a thinner export than you asked for.

Terminal window
# Everything
curl -L "https://api.getsteward.ai/api/v1/applications/{id}/export/json?screening=true&risk=true&documents=true&audit=true" \
-H "Authorization: Bearer stw_live_your_api_key_here"

The XML export carries an extra template parameter:

template Produces
full (default) The complete application record in Steward’s own XML shape
crs A CRS (Common Reporting Standard) fragment for regulatory filing
Terminal window
curl -L "https://api.getsteward.ai/api/v1/applications/{id}/export/xml?template=crs" \
-H "Authorization: Bearer stw_live_your_api_key_here" \
-o crs.xml

When a CRS export is missing information the standard requires, the export still succeeds. The gaps are reported rather than blocking the file, so you can generate a draft and fill in what is missing afterwards.

Note: GET /applications/{id}/export/crs-xml is the earlier standalone CRS endpoint. It still works, but export/xml?template=crs supersedes it and is the one to use in new integrations.

A business application’s FATCA/CRS declaration is part of the always-on record. This is the tax declaration the applicant completed during onboarding, unrelated to metadata, which is your own key-value data and is not included in exports at all.

How it is shaped depends on the format. CSV, PDF, and XML render one row per answer, keyed fatcaCrs.<field> alongside the other entity rows:

section,entity,key,label,value,verification
application,Northwind Capital Partners LP,name,Name,Northwind Capital Partners LP,verified (registry)
application,Northwind Capital Partners LP,fatcaCrs.isUsPerson,Is US person,true,
application,Northwind Capital Partners LP,fatcaCrs.giin,GIIN,ABC123.99999.SL.840,

JSON instead nests them under a fatcaCrs object, keyed by the plain field name:

{ "fatcaCrs": { "isUsPerson": true, "giin": "ABC123.99999.SL.840" } }

The answers themselves are the same either way:

Field Holds
fatcaCrs.isUsPerson Whether the entity is a US person
fatcaCrs.isSpecifiedUsPerson Whether it is a specified US person
fatcaCrs.fatcaClassification The FATCA classification chosen
fatcaCrs.institutionalClassification The institutional sub-classification
fatcaCrs.giin Global Intermediary Identification Number
fatcaCrs.noGiinReason Why no GIIN was supplied
fatcaCrs.crsEntityClassification The CRS entity classification
fatcaCrs.tin Taxpayer Identification Number
fatcaCrs.noTinExplanation Why no TIN was supplied

Two things to know before you build on these:

  • They are self-declared. Unlike entity fields, a FATCA/CRS answer is never checked against a registry or a document, so it carries no verification state. Treat it as the applicant’s assertion, not as verified data.
  • They come from the business record. Only a business application’s declaration is exported. A KYC (individual) export emits no fatcaCrs.* entries even where an individual answered the same questions.

A field the applicant answered with an empty string is still exported as an empty value. Only a question that was never asked is omitted. That distinction matters if you are reconciling exports: absent means not asked, empty means asked and left blank.

There is no FATCA XML template. template accepts full and crs only; FATCA data travels as the declaration fields above, in whichever format you request.

When you include documents, each entry carries a link to the file and a linkExpiresAt timestamp. Those links are valid for 7 days, and they are unauthenticated. Anyone holding the URL can fetch the file until it expires.

Two consequences worth designing around:

  • Treat an export containing document links as sensitive material in its own right, not just as a report.
  • Do not archive an export and expect the links to work later. Re-run the export when you need fresh links, or pull the bytes directly through GET /documents/download-all?applicationId=…, which streams the files themselves and never expires.

The PDF is rendered server-side and is the slowest of the four formats, so an application with many documents and a long audit trail takes meaningfully longer than the equivalent CSV. If you are exporting in bulk, prefer CSV or JSON, and give the PDF request a generous client timeout.

For several applications, create an asynchronous export instead of holding one request open. POST /applications/bulk/export accepts up to 100 selected application ids, a format of pdf, csv, xml, or json, and the same optional sections. Descendant applications are included automatically and may make totalCount larger than the submitted selection. For CRS, use the XML format with "template": "crs". POST /applications/bulk/export/crs-gaps accepts the selection and reports missing CRS fields before you create the job.

Terminal window
curl -X POST https://api.getsteward.ai/api/v1/applications/bulk/export \
-H "Authorization: Bearer stw_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"applicationIds": ["507f1f77bcf86cd799439011", "507f1f77bcf86cd799439012"],
"format": "json",
"sections": { "screening": true, "risk": true }
}'

Poll GET /applications/bulk/export/{jobId} until status is COMPLETED or FAILED. Partial application render failures can still finish with status COMPLETED when artifact creation succeeds; that result reports the successful completedCount and the exact failedApplicationIds. A run can instead reach FAILED when every application fails or when upload or processing cannot produce the artifact. Then call GET /applications/bulk/export/{jobId}/download for a signed URL. The URL is valid for 7 days; call the authenticated download endpoint again for a fresh URL after it expires. Jobs, errors, and download links are restricted to the API-key user that created the export, while Steward support staff retain support access.

You can subscribe to export.completed instead of polling indefinitely. Its payload includes the same counts and failed ids plus authenticated statusPath and downloadPath values. It never contains an S3 URL or credential.