Download a job's results
The whole result set as CSV or JSON, optionally filtered to one status. A large result set is answered with a short-lived presigned URL rather than inline.
Check complete before treating the file as the job's results. The export is read from an eventually-consistent index, so a job that has just flipped to completed can be exported before its last rows are visible. Every JSON response here (the inline one and the presigned-link one) carries complete, expected_rows and rows_missing, measured against the job's own processed_emails. A short JSON export is reported, not refused: the index normally catches up within seconds, so request it again.
A format=csv export that is known to be short is refused with 409 (retryable: true), not served. The bytes of a CSV have nowhere to carry the verdict, and a file that looks complete and is not is worse than no file. The refusal names the shortfall and offers format=json, which returns the rows that do exist together with the shortfall, inline. Note the size of a filtered export does not bound this: a selective filter on a large job can produce a handful of rows from a read that was badly short.
An empty read is not automatically a 404. If the job counts addresses it finished and none of their rows are readable, the route answers 409 with retryable: true rather than 404 No results found for this job. Retrying is the right next action and also distinguishes the two possible causes: the index catching up, which clears in seconds, or the rows having passed the plan's data-retention window, in which case they are gone. A job that genuinely produced no rows still answers 404.
The presigned URL is bound to the exact object version this request wrote, so the complete it arrives with describes the bytes it serves, even when two requests for the same export overlap. If that version cannot be bound, the route answers 503 rather than hand out an unbound link.
Request
- Base URL: https://api.kawaa.com
- URL: https://api.kawaa.com/v1/jobs/{id}/download
- Auth: one of:
- API key in header X-Api-Key
- HTTP bearer
- OAuth 2 (authorization code, authorization URL https://api.kawaa.com/oauth/authorize, token URL https://api.kawaa.com/oauth/token, scopes: verification:read)
Path parameters
The job identifier, a UUID.
Query parameters
Case-insensitive: the API lower-cases the query value before validating it, so CSV and csv are the same request. Expressed as a pattern rather than an enum, which can only list casings. Accepted values: csv, json.
Export only part of the job. FOUR OF THESE ARE SUMMARY BUCKETS, not exact verdicts, because they mirror the counts in the job summary: invalid also returns disposable addresses; risky also returns catch_all, role and spam_trap; unknown also returns rows with no stored status at all. valid is exact, and so are the finer four: catch_all, disposable, role and spam_trap each return only themselves. Building a suppression list from invalid therefore gets the disposable addresses too, which is usually what is wanted; ask for the exact verdict when it is not. all is accepted and is the explicit no-op: the API treats it as "no filter" and names it in the 400 it returns for anything else, so it is spelled out here rather than left to VerificationStatus, which does not contain it. Case-insensitive: the API lower-cases the query value before validating it, so ALL and all are the same request. Expressed as a pattern rather than an enum, which can only list casings. Accepted values: all, valid, invalid, risky, unknown, catch_all, disposable, role, spam_trap.
Response
The rows themselves, or a link to them when the set is large. Neither form is wrapped in the standard {success, data} envelope, so a deserializer expecting one rejects every successful download. format=csv answers with text/csv, not JSON.
Changes
No recorded changes to this operation across all 1 revision of this API.