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.
Formats
Section titled “Formats”| 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 |
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.
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.pdfChoosing what to include
Section titled “Choosing what to include”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.
# Everythingcurl -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"XML templates
Section titled “XML templates”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 |
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.xmlWhen 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-xmlis the earlier standalone CRS endpoint. It still works, butexport/xml?template=crssupersedes it and is the one to use in new integrations.
FATCA / CRS declarations
Section titled “FATCA / CRS declarations”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,verificationapplication,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.
Document links expire
Section titled “Document links expire”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.
Large applications
Section titled “Large applications”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.
Async bulk exports
Section titled “Async bulk exports”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.
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.