multipart/form-data with each file as a part of its own (see Two ways to send the files). There are two kinds of document.
Which company documents a corporate shareholder needs depends on its legal form: see Onboard a company. An entity’s own company documents are optional.
A signed tax form (W-9, W-8BEN, W-8BEN-E) is not a document: it goes to its own route. See Send a tax form.
Two ways to send the files
Both document routes take either body, with the same rules and the same answers. Choose per call; nothing else changes.
Send files over 10 MB as multipart. Base64 makes a file a third larger, so a 20 MB scan would be a request of almost 60 MB as JSON; as multipart it travels at its own size, and your client does not need to encode it.
Multipart
Let your HTTP client build the body. It writes thecontent-type header itself, with the boundary that separates the parts: do not set content-type yourself, since a header without that boundary answers 400 invalid_document. With curl, each -F adds one part:
A file part that does not belong to the document (a
file part on a passport, a back part on a passport, a front part on a company document), a part with another name, an empty file or more than two files answer 400 invalid_document, and details names the part when it can. Text parts with other names are ignored, as unknown JSON fields are.
JSON
Each file goes infiles[] with its mime, its side (identity documents) and its content in base64:
- Encoding: plain base64. A
data:<mime>;base64,prefix, line breaks, the URL-safe alphabet and missing padding are all accepted. mimemust match the file: it is checked against the file’s first bytes.- The whole request is at most about 31 MB, enough for both sides of a document at 10 MB each.
File rules
- Size: each file at most 10 MB as JSON (the file’s own size, before base64; about 13.3 MB once encoded), or 20 MB as multipart. Above 20 MB, reduce the scan rather than splitting it: one call takes one document. Check the size before sending: an oversized file is refused only after it has been uploaded.
- File types: identity documents are JPEG or PNG; company documents are JPEG, PNG or PDF.
- Identity files are read optically, so they must be real, legible images. A long edge of 1,000 to 1,500 pixels and JPEG quality 80 to 90 work well.
expiresAtis a date,YYYY-MM-DD; it is returned exactly as you send it.
Test files
Use these in sandbox; they pass every check:
Send them as they are in a multipart part, or encode one for the JSON
content field with:
Three ways a document is refused
Nothing is stored in any of them, so you can correct and send again.
A document of the wrong kind for its holder (an identity document for a company, a company document for a person) answers
422 business_rule_violation. A file over its limit (10 MB as JSON, 20 MB as multipart) answers 413 payload_too_large, and nothing is stored either.
Uploading again
Each call stores a new document; uploads are not deduplicated. Re-send a document only when:- it was refused (
400,415,422): nothing was stored; - it answered
502 file_upload_failed: nothing was stored; - it answered
502 document_outcome_unknownor502 verification_handoff_failed: the document was kept, and sending it again is safe; the extra copy is harmless.
GET /investors/{investorId}?include=documents or GET /investors/{investorId}/key-parties were all accepted: refused documents are never stored. A two-sided document appears as two entries, one per side. There is no call to delete a document.