# Jobs

## List all jobs

> Returns jobs matching the given query-parameter filters, up to 1001 per\
> page in descending \`createdAt\` order. Use \`createdAt\_lte\` on the last\
> record's \`createdAt\` (minus 1 ms) to page forward.\
> \
> There are two query modes depending on the \`type\` parameter:\
> \
> \- \*\*Parent jobs\*\* (\`type\` omitted, \`flow\`, \`retry\`, or \`bulk\_retry\`) —\
> &#x20; at least one of \`\_integrationId\`, \`\_flowId\`, \`\_exportId\`, \`\_importId\`,\
> &#x20; \`\_flowJobId\`, \`createdAt\_gte\`, or \`createdAt\_lte\` is \*\*required\*\*.\
> &#x20; Omitting all returns 400 \`invalid\_query\` with message:\
> &#x20; \`"For parent jobs, query parameters must contain either \\"\_integrationId\\" or \\"\_jobId\\" or \\"createdAt\\""\`.\
> &#x20; (Despite the message text, \`\_flowId\`, \`\_exportId\`, \`\_importId\`, and\
> &#x20; \`\_flowJobId\` also satisfy the check.)\
> \- \*\*Child jobs\*\* (\`type=export\` or \`type=import\`) — requires\
> &#x20; \`\_flowJobId\` or a resource ID filter (\`\_exportId\` / \`\_importId\`).\
> &#x20; Omitting both returns 400 \`invalid\_query\` with message:\
> &#x20; \`"For child jobs, query parameters must contain either \\"\_flowJobId\\" or \\"resourceId\\""\`.\
> &#x20; Returns the export/import sub-jobs within a parent flow job.\
> \
> AI guidance:\
> \- Date filters accept ISO 8601 (\`2026-04-29T00:00:00.000Z\`), ISO\
> &#x20; without millis (\`2026-04-29T00:00:00Z\`), plain date (\`2026-04-29\`),\
> &#x20; or epoch milliseconds (\`1714521600000\`).\
> \- Caution: when \`numError\_gte\` or \`numError\_lte\` is combined with\
> &#x20; \`\_integrationId\`, the query is routed to ClickHouse which rejects\
> &#x20; plain-date format — use ISO 8601 with millis instead.\
> \- This endpoint does \*\*not\*\* have a built-in \`nextPageURL\` cursor. To\
> &#x20; page, take the \`createdAt\` of the \*\*last\*\* record in the current page,\
> &#x20; subtract 1 millisecond, and pass that as \`createdAt\_lte\` in the next\
> &#x20; request.\
> \- The list response omits \`clickhousePurgeAt\` even when the GET-by-ID\
> &#x20; response includes it.\
> \- Child jobs (type \`export\` / \`import\`) cannot be fetched via\
> &#x20; \`GET /v1/jobs/{\_id}\` — use this list endpoint with \`\_flowJobId\`\
> &#x20; instead.\
> \- For delta exports use \`createdAt\_gte\` with a saved checkpoint.\
> \- All \`\_id\`-style query parameters require the underscore prefix\
> &#x20; (e.g. \`\_integrationId\` not \`integrationId\`).\
> \- Unknown query parameters are silently ignored.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/jobs":{"get":{"operationId":"listJobs","tags":["Jobs"],"summary":"List all jobs","description":"Returns jobs matching the given query-parameter filters, up to 1001 per\npage in descending `createdAt` order. Use `createdAt_lte` on the last\nrecord's `createdAt` (minus 1 ms) to page forward.\n\nThere are two query modes depending on the `type` parameter:\n\n- **Parent jobs** (`type` omitted, `flow`, `retry`, or `bulk_retry`) —\n  at least one of `_integrationId`, `_flowId`, `_exportId`, `_importId`,\n  `_flowJobId`, `createdAt_gte`, or `createdAt_lte` is **required**.\n  Omitting all returns 400 `invalid_query` with message:\n  `\"For parent jobs, query parameters must contain either \\\"_integrationId\\\" or \\\"_jobId\\\" or \\\"createdAt\\\"\"`.\n  (Despite the message text, `_flowId`, `_exportId`, `_importId`, and\n  `_flowJobId` also satisfy the check.)\n- **Child jobs** (`type=export` or `type=import`) — requires\n  `_flowJobId` or a resource ID filter (`_exportId` / `_importId`).\n  Omitting both returns 400 `invalid_query` with message:\n  `\"For child jobs, query parameters must contain either \\\"_flowJobId\\\" or \\\"resourceId\\\"\"`.\n  Returns the export/import sub-jobs within a parent flow job.\n\nAI guidance:\n- Date filters accept ISO 8601 (`2026-04-29T00:00:00.000Z`), ISO\n  without millis (`2026-04-29T00:00:00Z`), plain date (`2026-04-29`),\n  or epoch milliseconds (`1714521600000`).\n- Caution: when `numError_gte` or `numError_lte` is combined with\n  `_integrationId`, the query is routed to ClickHouse which rejects\n  plain-date format — use ISO 8601 with millis instead.\n- This endpoint does **not** have a built-in `nextPageURL` cursor. To\n  page, take the `createdAt` of the **last** record in the current page,\n  subtract 1 millisecond, and pass that as `createdAt_lte` in the next\n  request.\n- The list response omits `clickhousePurgeAt` even when the GET-by-ID\n  response includes it.\n- Child jobs (type `export` / `import`) cannot be fetched via\n  `GET /v1/jobs/{_id}` — use this list endpoint with `_flowJobId`\n  instead.\n- For delta exports use `createdAt_gte` with a saved checkpoint.\n- All `_id`-style query parameters require the underscore prefix\n  (e.g. `_integrationId` not `integrationId`).\n- Unknown query parameters are silently ignored.","parameters":[{"name":"_integrationId","in":"query","schema":{"type":"string"},"description":"Filter by integration ID. Satisfies the required-param check."},{"name":"_exportId","in":"query","schema":{"type":"string"},"description":"Filter by export ID. Satisfies the required-param check."},{"name":"_importId","in":"query","schema":{"type":"string"},"description":"Filter by import ID. Satisfies the required-param check."},{"name":"_flowId","in":"query","schema":{"type":"string"},"description":"Filter by flow ID. Satisfies the required-param check."},{"name":"_flowJobId","in":"query","schema":{"type":"string"},"description":"Filter by parent flow-job ID. Satisfies the required-param check.\nRequired when querying child jobs (`type=export` or `type=import`)."},{"name":"_flowId_in","in":"query","schema":{"type":"string"},"description":"Comma-separated list of flow IDs to match. Works as an additional\nfilter but does **not** satisfy the required-param check alone.\n`flowId_in` (without underscore) is accepted as an alias."},{"name":"status_in","in":"query","schema":{"type":"string"},"description":"Comma-separated list of status values to match (e.g.\n`completed,failed`). Works as an additional filter but does\n**not** satisfy the required-param check alone."},{"name":"createdAt_lte","in":"query","schema":{"type":"string"},"description":"Return jobs created at or before this timestamp. Accepts ISO 8601,\nplain date, or epoch milliseconds. Satisfies the required-param\ncheck."},{"name":"createdAt_gte","in":"query","schema":{"type":"string"},"description":"Return jobs created at or after this timestamp. Accepts ISO 8601,\nplain date, or epoch milliseconds. Satisfies the required-param\ncheck."},{"name":"status","in":"query","schema":{"type":"string","enum":["queued","running","completed","failed","canceled","canceling","retrying"]},"description":"Filter by job status. Server-validated — invalid values (including\nthe double-l spelling `cancelled`) return 400 `invalid_query_param`."},{"name":"numSuccess_lte","in":"query","schema":{"type":"integer"},"description":"Filter to jobs with success count ≤ this value."},{"name":"numSuccess_gte","in":"query","schema":{"type":"integer"},"description":"Filter to jobs with success count ≥ this value."},{"name":"numIgnore_lte","in":"query","schema":{"type":"integer"},"description":"Filter to jobs with ignore count ≤ this value."},{"name":"numIgnore_gte","in":"query","schema":{"type":"integer"},"description":"Filter to jobs with ignore count ≥ this value."},{"name":"numError_gte","in":"query","schema":{"type":"integer"},"description":"Filter to jobs with error count ≥ this value. When combined with\n`_integrationId`, the query routes to ClickHouse which rejects\nplain-date `createdAt` values — use full ISO 8601."},{"name":"numError_lte","in":"query","schema":{"type":"integer"},"description":"Filter to jobs with error count ≤ this value. Same ClickHouse\ndate-format caveat as `numError_gte`."},{"name":"type","in":"query","schema":{"type":"string","enum":["flow","export","import","retry","bulk_retry"]},"description":"Filter by job type. `flow`, `retry`, and `bulk_retry` are\nparent-level jobs; `export` and `import` are child jobs (require\n`_flowJobId` or a resource-ID filter). Unrecognized values silently\nreturn 204."}],"responses":{"200":{"description":"Array of job records matching the filters.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Job"}}}}},"204":{"description":"No jobs match the given filters."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## List in-progress jobs (dashboard)

> Returns a paginated list of currently in-progress jobs for the dashboard — jobs whose \`status\` is one of\
> \`queued\`, \`running\`, or \`canceling\`. Jobs that have reached a terminal state (\`completed\`, \`failed\`,\
> \`canceled\`, \`retried\`) are \*\*not\*\* returned; use \`POST /v1/flows/runs/stats\` for run history.\
> \
> The request body contains all filters — there are no query-string parameters.\
> \
> Pagination is body-paginated: when a \`nextPageURL\` is present in the response, follow it to fetch the next\
> page. The UI strips a leading \`/api\` prefix from the returned URL before reissuing the call.\
> \
> AI guidance:\
> \- This endpoint reflects \*live\* state — poll sparingly (the UI polls on the order of seconds).\
> \- To narrow to a specific flow or integration use \`\_flowIds\` / \`\_integrationIds\` — these are AND-combined.\
> \- A \`204 No Content\` response means there are no matching jobs (not an error).

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JobsCurrentRequest":{"type":"object","description":"Request body for `POST /v1/jobs/current`.\nThe UI uses this to fetch in-progress jobs for the dashboard.\n","properties":{"_integrationIds":{"type":"array","description":"Optional filter to only return jobs for these integration ids.","items":{"type":"string","format":"objectId"}},"_flowIds":{"type":"array","description":"Optional filter to only return jobs for these flow ids.","items":{"type":"string","format":"objectId"}},"status":{"type":"array","description":"Optional filter for in-progress job statuses.\nTerminal statuses (`completed`, `failed`, `canceled`, `retried`) are rejected with HTTP 400 by this endpoint —\nuse `POST /v1/flows/runs/stats` for completed-run history.\n","items":{"type":"string","enum":["queued","running","canceling"]}},"applicationIds":{"type":"array","description":"Optional filter by application ids.","items":{"type":"string"}},"category":{"type":"string","description":"Optional category filter (e.g., `edi`)."},"time_gt":{"type":"integer","format":"int64","description":"Optional filter for jobs with `createdAt`/time greater than this epoch milliseconds."},"time_lte":{"type":"integer","format":"int64","description":"Optional filter for jobs with `createdAt`/time less than or equal to this epoch milliseconds."}},"required":[]},"JobsCurrentResponse":{"type":"object","description":"Response envelope for `POST /v1/jobs/current`.","properties":{"jobs":{"type":"array","description":"Current (in-progress) jobs.","items":{"$ref":"#/components/schemas/JobWithChildren"}},"pagingPostBody":{"type":"object","description":"Cursor for the next page. Absent on the last (or only) page. Pagination is **body-based**:\nPOST this object back to the same endpoint as the next request body to fetch the next page.\nEchoes the caller's filter plus a server-added watermark (`endedOnOrBefore`). Single-page\nresponses omit this field entirely.","properties":{"endedOnOrBefore":{"type":"string","format":"date-time","description":"Server-added cursor watermark — only jobs with `endedAt <= this` are included on the next page."}}}}},"JobWithChildren":{"allOf":[{"$ref":"#/components/schemas/Job"},{"type":"object","description":"Job plus any child jobs (job family view).","properties":{"children":{"type":"array","readOnly":true,"description":"Child jobs (export/import) that are part of this job family.","items":{"$ref":"#/components/schemas/Job"}}}}]},"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/jobs/current":{"post":{"operationId":"listCurrentJobs","tags":["Jobs"],"summary":"List in-progress jobs (dashboard)","description":"Returns a paginated list of currently in-progress jobs for the dashboard — jobs whose `status` is one of\n`queued`, `running`, or `canceling`. Jobs that have reached a terminal state (`completed`, `failed`,\n`canceled`, `retried`) are **not** returned; use `POST /v1/flows/runs/stats` for run history.\n\nThe request body contains all filters — there are no query-string parameters.\n\nPagination is body-paginated: when a `nextPageURL` is present in the response, follow it to fetch the next\npage. The UI strips a leading `/api` prefix from the returned URL before reissuing the call.\n\nAI guidance:\n- This endpoint reflects *live* state — poll sparingly (the UI polls on the order of seconds).\n- To narrow to a specific flow or integration use `_flowIds` / `_integrationIds` — these are AND-combined.\n- A `204 No Content` response means there are no matching jobs (not an error).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsCurrentRequest"}}}},"responses":{"200":{"description":"One page of in-progress jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsCurrentResponse"}}}},"204":{"description":"No in-progress jobs match the filter."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Get per-flow run statistics (dashboard aggregates)

> Returns \*\*per-flow aggregate\*\* run statistics — one element of \`stats\[]\` per flow that has at least\
> one run matching the request filter. Each aggregate carries totals (\`numRuns\`, \`numSuccess\`,\
> \`numError\`, \`numIgnore\`), the currently-open error count (\`numOpenError\`), resolution attribution\
> (\`numResolvedByAuto\` / \`numResolvedByUser\`), average runtime (\`avgRuntime\`), and timestamps\
> (\`lastExecutedAt\`, \`lastErrorAt\`) plus a minimal inlined \`flow{}\` object for rendering.\
> \
> The Celigo dashboard uses this to paint its "All flows" summary in one call. Filters (\`\_flowIds\`,\
> \`\_integrationIds\`, \`time\_gt\`, \`time\_lte\`, …) narrow which runs are rolled up into each aggregate —\
> they do \*\*not\*\* filter which flows appear; flows with zero matching runs are simply omitted.\
> \
> AI guidance:\
> \- Use this for "what's the current health of each flow?" dashboards, not for per-run history.\
> \- For a list of individual job records, call \`GET /v1/jobs?\_flowId=...\` instead — that endpoint\
> &#x20; returns one record per run (paginated via Link headers), with full job-level fields.\
> \- For in-progress jobs, use \`POST /v1/jobs/current\`.\
> \- \`numOpenError\` reflects \*live\* state — polling this is how the dashboard watches the error queue\
> &#x20; drain as users resolve or retry.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"FlowRunsStatsRequest":{"allOf":[{"$ref":"#/components/schemas/JobsCurrentRequest"},{"type":"object","description":"Request body for `POST /v1/flows/runs/stats`. Shares its filter shape with `POST /v1/jobs/current`\n(`_integrationIds`, `_flowIds`, `time_gt`, `time_lte`, …), but the response is a set of\n**per-flow aggregates** rather than individual job records. Filters narrow which runs are rolled\nup into each aggregate."}]},"JobsCurrentRequest":{"type":"object","description":"Request body for `POST /v1/jobs/current`.\nThe UI uses this to fetch in-progress jobs for the dashboard.\n","properties":{"_integrationIds":{"type":"array","description":"Optional filter to only return jobs for these integration ids.","items":{"type":"string","format":"objectId"}},"_flowIds":{"type":"array","description":"Optional filter to only return jobs for these flow ids.","items":{"type":"string","format":"objectId"}},"status":{"type":"array","description":"Optional filter for in-progress job statuses.\nTerminal statuses (`completed`, `failed`, `canceled`, `retried`) are rejected with HTTP 400 by this endpoint —\nuse `POST /v1/flows/runs/stats` for completed-run history.\n","items":{"type":"string","enum":["queued","running","canceling"]}},"applicationIds":{"type":"array","description":"Optional filter by application ids.","items":{"type":"string"}},"category":{"type":"string","description":"Optional category filter (e.g., `edi`)."},"time_gt":{"type":"integer","format":"int64","description":"Optional filter for jobs with `createdAt`/time greater than this epoch milliseconds."},"time_lte":{"type":"integer","format":"int64","description":"Optional filter for jobs with `createdAt`/time less than or equal to this epoch milliseconds."}},"required":[]},"FlowRunsStatsResponse":{"type":"object","description":"One page of per-flow run-statistics aggregates. Despite the endpoint's location under `flows/runs/`,\neach element of `stats[]` is **not** an individual job record — it's the aggregated summary for one\nflow across all matching runs (counts, timings, and the most recent timestamps). The dashboard uses\nthis to render its per-flow \"last run / success rate / open errors\" cards in a single call.\n\nTo list individual job records (one per run), use `GET /v1/jobs?_flowId=...` instead.","properties":{"stats":{"type":"array","description":"Per-flow aggregate entries. One element per flow that has at least one run matching the request\nfilter.","items":{"$ref":"#/components/schemas/FlowRunStatsEntry"}},"pagingPostBody":{"type":"object","description":"Cursor for the next page. Absent on the last (or only) page. Pagination is **body-based**:\nPOST this object back to the same endpoint as the next request body to fetch the next page.\nThe object echoes the caller's filter plus a server-added watermark\n(`endedOnOrBefore`) that carries the cursor position. Single-page responses (typical for\nnormal account sizes) omit this field entirely.","properties":{"endedOnOrBefore":{"type":"string","format":"date-time","description":"Server-added cursor watermark — only runs with `endedAt <= this` are included on the next page."}}}},"required":["stats"]},"FlowRunStatsEntry":{"type":"object","description":"Per-flow aggregate across all matching runs. Produced by `POST /v1/flows/runs/stats` and used to\npopulate the Celigo dashboard's per-flow summary cards.","properties":{"_flowId":{"type":"string","format":"objectId","description":"Id of the flow this entry aggregates."},"_integrationId":{"type":"string","format":"objectId","description":"Id of the flow's parent integration. Omitted for standalone flows that aren't part of an\nintegration."},"numRuns":{"type":"integer","minimum":0,"description":"Total number of runs that matched the request filter."},"numPages":{"type":"integer","minimum":0,"description":"Total pages processed across those runs (one run can produce multiple pages when the source\nexport paginates)."},"numSuccess":{"type":"integer","minimum":0,"description":"Records that completed successfully across all matched runs."},"numError":{"type":"integer","minimum":0,"description":"Records that failed across all matched runs. Distinct from `numOpenError` — this is the\nlifetime-of-those-runs error count, not the currently-unresolved count."},"numIgnore":{"type":"integer","minimum":0,"description":"Records that were ignored (filtered out by `inputFilter` / `outputFilter`) across all matched runs."},"numOpenError":{"type":"integer","minimum":0,"description":"Currently **open** (unresolved) errors on this flow. Drops when errors are resolved or retried."},"numResolvedByAuto":{"type":"integer","minimum":0,"description":"Errors that were auto-resolved by a successful retry."},"numResolvedByUser":{"type":"integer","minimum":0,"description":"Errors that a user manually marked resolved."},"avgRuntime":{"type":"number","description":"Mean job runtime in milliseconds across matched runs."},"lastExecutedAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent matching run (any status)."},"lastErrorAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent open error. Omitted when `numOpenError` is 0."},"flow":{"type":"object","description":"Minimal flow metadata inlined for rendering convenience — equivalent to `GET /v1/flows/{_flowId}` with most fields stripped.","properties":{"_id":{"type":"string","format":"objectId","description":"Flow id (matches the outer `_flowId`)."},"name":{"type":"string","description":"Flow name."},"_integrationId":{"type":"string","format":"objectId","description":"Parent integration id. Omitted for standalone flows."},"integrationName":{"type":"string","description":"Parent integration name. Omitted for standalone flows."}},"required":["_id","name"]}},"required":["_flowId","numRuns","numSuccess","numError","numIgnore","numOpenError","flow"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/flows/runs/stats":{"post":{"operationId":"getFlowRunsStats","tags":["Jobs"],"summary":"Get per-flow run statistics (dashboard aggregates)","description":"Returns **per-flow aggregate** run statistics — one element of `stats[]` per flow that has at least\none run matching the request filter. Each aggregate carries totals (`numRuns`, `numSuccess`,\n`numError`, `numIgnore`), the currently-open error count (`numOpenError`), resolution attribution\n(`numResolvedByAuto` / `numResolvedByUser`), average runtime (`avgRuntime`), and timestamps\n(`lastExecutedAt`, `lastErrorAt`) plus a minimal inlined `flow{}` object for rendering.\n\nThe Celigo dashboard uses this to paint its \"All flows\" summary in one call. Filters (`_flowIds`,\n`_integrationIds`, `time_gt`, `time_lte`, …) narrow which runs are rolled up into each aggregate —\nthey do **not** filter which flows appear; flows with zero matching runs are simply omitted.\n\nAI guidance:\n- Use this for \"what's the current health of each flow?\" dashboards, not for per-run history.\n- For a list of individual job records, call `GET /v1/jobs?_flowId=...` instead — that endpoint\n  returns one record per run (paginated via Link headers), with full job-level fields.\n- For in-progress jobs, use `POST /v1/jobs/current`.\n- `numOpenError` reflects *live* state — polling this is how the dashboard watches the error queue\n  drain as users resolve or retry.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowRunsStatsRequest"}}}},"responses":{"200":{"description":"One page of per-flow aggregates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowRunsStatsResponse"}}}},"204":{"description":"No runs match the filter on any flow."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Batch-fetch job families

> Returns job families for an array of job ids, in one request. Each item in the response array has the same\
> shape as a single \`GET /v1/jobs/{\_id}/family\` call (a parent job with inlined \`children\`).\
> \
> \*\*Size limit: 1000 ids per request.\*\* The server rejects requests with more than 1000 entries with HTTP\
> \*\*403\*\* (not 400) and \`{code: "invalid\_request", message: "Number of objects in the request exceeds\
> maximum allowed limit 1000"}\`. The Celigo UI chunks at 50 for its own UX reasons, but the API ceiling\
> is 1000.\
> \
> \*\*Mixed-id behavior (asymmetric):\*\*\
> \- Valid + unknown 24-hex ids in the same array → \*\*200\*\* with only the resolved entries; unknown ids are\
> &#x20; silently dropped (no \`errors\[]\` alongside).\
> \- All ids unknown → \*\*404\*\* with \`{errors: \[{code: "invalid\_ref", source: "internal", message: "Job not\
> &#x20; found: \<id>"}]}\`.\
> \- Any id that isn't a 24-char hex string anywhere in the array → \*\*400\*\* \`invalid\_ref "Please provide\
> &#x20; a valid \_id."\` — the whole request fails.\
> \- Duplicate ids are \*\*deduped\*\* server-side (same id ×N → one entry).\
> \- Empty array \`\[]\` or non-array body (e.g. \`{}\`) → \*\*400\*\* \`invalid\_request "Request body should be an\
> &#x20; ObjectID array."\`.\
> \- Missing \`Content-Type: application/json\` → \*\*415\*\* \`{message: "Content-Type should equal\
> &#x20; application/json"}\`.\
> \
> AI guidance:\
> \- Use this when building a list view (e.g. "show the last 50 flow runs and their child status") — one call\
> &#x20; instead of N round-trips.\
> \- The response array has no documented ordering guarantee; match items by \`\_id\` rather than by index.\
> \- Unknown ids are silently dropped; callers that need to detect missing ids must diff the request and\
> &#x20; response id sets themselves.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JobsFamilyBatchRequest":{"type":"array","description":"Array of job ids to fetch family information for (max ~50 ids per request).","items":{"type":"string","format":"objectId"}},"JobWithChildren":{"allOf":[{"$ref":"#/components/schemas/Job"},{"type":"object","description":"Job plus any child jobs (job family view).","properties":{"children":{"type":"array","readOnly":true,"description":"Child jobs (export/import) that are part of this job family.","items":{"$ref":"#/components/schemas/Job"}}}}]},"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/jobs/family":{"post":{"operationId":"getJobFamilyBatch","tags":["Jobs"],"summary":"Batch-fetch job families","description":"Returns job families for an array of job ids, in one request. Each item in the response array has the same\nshape as a single `GET /v1/jobs/{_id}/family` call (a parent job with inlined `children`).\n\n**Size limit: 1000 ids per request.** The server rejects requests with more than 1000 entries with HTTP\n**403** (not 400) and `{code: \"invalid_request\", message: \"Number of objects in the request exceeds\nmaximum allowed limit 1000\"}`. The Celigo UI chunks at 50 for its own UX reasons, but the API ceiling\nis 1000.\n\n**Mixed-id behavior (asymmetric):**\n- Valid + unknown 24-hex ids in the same array → **200** with only the resolved entries; unknown ids are\n  silently dropped (no `errors[]` alongside).\n- All ids unknown → **404** with `{errors: [{code: \"invalid_ref\", source: \"internal\", message: \"Job not\n  found: <id>\"}]}`.\n- Any id that isn't a 24-char hex string anywhere in the array → **400** `invalid_ref \"Please provide\n  a valid _id.\"` — the whole request fails.\n- Duplicate ids are **deduped** server-side (same id ×N → one entry).\n- Empty array `[]` or non-array body (e.g. `{}`) → **400** `invalid_request \"Request body should be an\n  ObjectID array.\"`.\n- Missing `Content-Type: application/json` → **415** `{message: \"Content-Type should equal\n  application/json\"}`.\n\nAI guidance:\n- Use this when building a list view (e.g. \"show the last 50 flow runs and their child status\") — one call\n  instead of N round-trips.\n- The response array has no documented ordering guarantee; match items by `_id` rather than by index.\n- Unknown ids are silently dropped; callers that need to detect missing ids must diff the request and\n  response id sets themselves.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsFamilyBatchRequest"}}}},"responses":{"200":{"description":"An array of job families, one per **resolved** id (unknown ids silently dropped).","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JobWithChildren"}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"},"415":{"description":"Returned when the request is missing the `Content-Type: application/json` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a job

> Returns a single job record. Jobs are read-only platform-generated records of flow/export/import execution;\
> they are created by the platform when runs happen and cannot be directly created or updated through this API.\
> \
> AI guidance:\
> \- This endpoint only works for \*\*parent\*\* jobs (\`type=flow\`, \`retry\`,\
> &#x20; \`bulk\_retry\`). Child jobs (\`type=export\` or \`type=import\`) return\
> &#x20; 404 from this endpoint — retrieve them via \`GET /v1/jobs\` with\
> &#x20; \`\_flowJobId\` instead.\
> \- The response includes \`clickhousePurgeAt\` when present, which is\
> &#x20; omitted from the list endpoint (\`GET /v1/jobs\`).\
> \- Use this to inspect a specific run's status, counters (\`numError\`, \`numOpenError\`, \`numSuccess\`, …), and\
> &#x20; timing (\`startedAt\`, \`endedAt\`).\
> \- For the full parent+children view of a flow run, prefer \`GET /v1/jobs/{\_id}/family\` instead.\
> \- For a multi-job lookup, prefer \`POST /v1/jobs/family\` to avoid N API calls.\
> \- An invalid (non-ObjectId) \`\_id\` format returns 400 \`invalid\_ref\`\
> &#x20; with message \`"Please provide a valid \_jobId."\`.\
> \- A valid but non-existent \`\_id\` returns 404 \`invalid\_ref\`\
> &#x20; with message \`"Job not found."\`.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/jobs/{_id}":{"get":{"operationId":"getJobById","tags":["Jobs"],"summary":"Get a job","description":"Returns a single job record. Jobs are read-only platform-generated records of flow/export/import execution;\nthey are created by the platform when runs happen and cannot be directly created or updated through this API.\n\nAI guidance:\n- This endpoint only works for **parent** jobs (`type=flow`, `retry`,\n  `bulk_retry`). Child jobs (`type=export` or `type=import`) return\n  404 from this endpoint — retrieve them via `GET /v1/jobs` with\n  `_flowJobId` instead.\n- The response includes `clickhousePurgeAt` when present, which is\n  omitted from the list endpoint (`GET /v1/jobs`).\n- Use this to inspect a specific run's status, counters (`numError`, `numOpenError`, `numSuccess`, …), and\n  timing (`startedAt`, `endedAt`).\n- For the full parent+children view of a flow run, prefer `GET /v1/jobs/{_id}/family` instead.\n- For a multi-job lookup, prefer `POST /v1/jobs/family` to avoid N API calls.\n- An invalid (non-ObjectId) `_id` format returns 400 `invalid_ref`\n  with message `\"Please provide a valid _jobId.\"`.\n- A valid but non-existent `_id` returns 404 `invalid_ref`\n  with message `\"Job not found.\"`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Job id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"The job record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get a job and its children

> Returns a single job record (as parent) with all of its child jobs inlined under \`children\`.\
> \
> A "job family" maps to one flow execution: the parent is a \`type: "flow"\` job and the children are the\
> \`export\` / \`import\` / \`retry\` jobs that ran as part of it. For non-flow jobs (a standalone export run, or a\
> retry), \`children\` may be empty.\
> \
> AI guidance:\
> \- Use this for a single flow-run detail view. For fetching many families at once, batch via\
> &#x20; \`POST /v1/jobs/family\`.\
> \- Aggregate error counts (\`numError\`, \`numOpenError\`, \`numSuccess\`) across \`children\` for a per-run summary;\
> &#x20; the parent's counters may not include bulk-retry jobs spawned after the initial run.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JobWithChildren":{"allOf":[{"$ref":"#/components/schemas/Job"},{"type":"object","description":"Job plus any child jobs (job family view).","properties":{"children":{"type":"array","readOnly":true,"description":"Child jobs (export/import) that are part of this job family.","items":{"$ref":"#/components/schemas/Job"}}}}]},"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/jobs/{_id}/family":{"get":{"operationId":"getJobFamily","tags":["Jobs"],"summary":"Get a job and its children","description":"Returns a single job record (as parent) with all of its child jobs inlined under `children`.\n\nA \"job family\" maps to one flow execution: the parent is a `type: \"flow\"` job and the children are the\n`export` / `import` / `retry` jobs that ran as part of it. For non-flow jobs (a standalone export run, or a\nretry), `children` may be empty.\n\nAI guidance:\n- Use this for a single flow-run detail view. For fetching many families at once, batch via\n  `POST /v1/jobs/family`.\n- Aggregate error counts (`numError`, `numOpenError`, `numSuccess`) across `children` for a per-run summary;\n  the parent's counters may not include bulk-retry jobs spawned after the initial run.","parameters":[{"name":"_id","in":"path","required":true,"description":"Job id. Typically a parent flow job id, but any job id is accepted.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Job family (parent with inlined children).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobWithChildren"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Cancel a job

> Requests cancellation of a running or queued job. The job's \`status\` transitions to \`canceling\` and, once the\
> platform has stopped in-flight work, to \`canceled\`. This is \*\*not\*\* synchronous — the response returns the\
> updated job record with \`status: "canceling"\`; consumers should poll (e.g. \`GET /v1/jobs/{\_id}\`) to observe\
> the final \`canceled\` state.\
> \
> Only jobs that are still in progress (\`queued\`, \`running\`, \`retrying\`) can be cancelled. Cancelling a job\
> that is already terminal returns an error.\
> \
> AI guidance:\
> \- Prefer cancelling at the flow-run (parent \`type: "flow"\`) level rather than individual export/import\
> &#x20; children — child cancellations can leave the parent in an inconsistent state.\
> \- After calling this, verify the terminal \`canceled\` state before reporting success to the user.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/jobs/{_id}/cancel":{"put":{"operationId":"cancelJob","tags":["Jobs"],"summary":"Cancel a job","description":"Requests cancellation of a running or queued job. The job's `status` transitions to `canceling` and, once the\nplatform has stopped in-flight work, to `canceled`. This is **not** synchronous — the response returns the\nupdated job record with `status: \"canceling\"`; consumers should poll (e.g. `GET /v1/jobs/{_id}`) to observe\nthe final `canceled` state.\n\nOnly jobs that are still in progress (`queued`, `running`, `retrying`) can be cancelled. Cancelling a job\nthat is already terminal returns an error.\n\nAI guidance:\n- Prefer cancelling at the flow-run (parent `type: \"flow\"`) level rather than individual export/import\n  children — child cancellations can leave the parent in an inconsistent state.\n- After calling this, verify the terminal `canceled` state before reporting success to the user.","parameters":[{"name":"_id","in":"path","required":true,"description":"Job id to cancel.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Updated job record with `status: \"canceling\"`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"The job is already in a terminal state and cannot be cancelled.\nError code `job_already_ended`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get signed URL(s) to download job files

> Returns short-lived S3 pre-signed URLs for downloading files produced by the job (e.g. the rows exported to\
> a CSV, an error-record dump, or a page-processor artifact). The URLs are typically valid for \~15 minutes.\
> \
> If \`fileIds\` is omitted in the request body, all of the job's current file artifacts are returned. If\
> provided, only the matching files are included.\
> \
> AI guidance:\
> \- Inspect the job's \`files\[]\` array first (via \`GET /v1/jobs/{\_id}\`) to discover what file IDs exist.\
> \- If the job has no files (common for \`import\` child jobs, or for jobs whose artifacts have been purged\
> &#x20; after \`purgeAt\`), this endpoint returns \`204 No Content\`.\
> \- Response shape: one of \`signedURL\` (single) or \`signedURLs\` (array) — check both.\
> \- The URL expires — fetch and stream immediately, do not persist.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JobFilesSignedUrlRequest":{"type":"object","description":"Request body for `POST /v1/jobs/{_id}/files/signedURL`.\nProvide `fileIds` to request signed URLs for specific files.\n","properties":{"fileIds":{"type":"array","description":"Optional list of job file ids to download.","items":{"type":"string"}}}},"JobFilesSignedUrlResponse":{"type":"object","description":"Signed URL response for downloading job files.","properties":{"signedURL":{"type":["string","null"],"description":"A single signed URL (when only one file is returned)."},"signedURLs":{"type":"array","description":"Multiple signed URLs (when multiple files are returned).","items":{"type":"string"}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/jobs/{_id}/files/signedURL":{"post":{"operationId":"getJobFilesSignedUrl","tags":["Jobs"],"summary":"Get signed URL(s) to download job files","description":"Returns short-lived S3 pre-signed URLs for downloading files produced by the job (e.g. the rows exported to\na CSV, an error-record dump, or a page-processor artifact). The URLs are typically valid for ~15 minutes.\n\nIf `fileIds` is omitted in the request body, all of the job's current file artifacts are returned. If\nprovided, only the matching files are included.\n\nAI guidance:\n- Inspect the job's `files[]` array first (via `GET /v1/jobs/{_id}`) to discover what file IDs exist.\n- If the job has no files (common for `import` child jobs, or for jobs whose artifacts have been purged\n  after `purgeAt`), this endpoint returns `204 No Content`.\n- Response shape: one of `signedURL` (single) or `signedURLs` (array) — check both.\n- The URL expires — fetch and stream immediately, do not persist.","parameters":[{"name":"_id","in":"path","required":true,"description":"Job id whose files should be downloaded.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobFilesSignedUrlRequest"}}}},"responses":{"200":{"description":"One or more signed URLs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobFilesSignedUrlResponse"}}}},"204":{"description":"Job has no downloadable files (or requested `fileIds` matched none)."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Purge a job's stored files

> Deletes \*\*all\*\* file artifacts associated with the job (exported rows, error-record dumps, page-processor\
> artifacts, etc.) from underlying storage. After a successful call, \`GET /v1/jobs/{\_id}\` will show an empty\
> \`files\[]\` array and \`POST /v1/jobs/{\_id}/files/signedURL\` will return \`204 No Content\`.\
> \
> The job record itself is retained — only the files are purged.\
> \
> AI guidance:\
> \- This is irreversible. Confirm with the user before calling, especially for jobs that still have error\
> &#x20; records the user may want to download.\
> \- The platform also purges files automatically at \`purgeAt\` / \`clickhousePurgeAt\`; manual purge is only\
> &#x20; needed for storage-quota management or compliance workflows.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/jobs/{_id}/files":{"delete":{"operationId":"purgeJobFiles","tags":["Jobs"],"summary":"Purge a job's stored files","description":"Deletes **all** file artifacts associated with the job (exported rows, error-record dumps, page-processor\nartifacts, etc.) from underlying storage. After a successful call, `GET /v1/jobs/{_id}` will show an empty\n`files[]` array and `POST /v1/jobs/{_id}/files/signedURL` will return `204 No Content`.\n\nThe job record itself is retained — only the files are purged.\n\nAI guidance:\n- This is irreversible. Confirm with the user before calling, especially for jobs that still have error\n  records the user may want to download.\n- The platform also purges files automatically at `purgeAt` / `clickhousePurgeAt`; manual purge is only\n  needed for storage-quota management or compliance workflows.","parameters":[{"name":"_id","in":"path","required":true,"description":"Job id whose files should be purged.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Files purged successfully."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get a signed URL for job diagnostics

> Returns a short-lived S3 pre-signed URL pointing to a diagnostic archive (\`.zip\`) for the given job. The\
> archive contains server-side traces/logs that Celigo support uses to debug execution failures.\
> \
> The URL is typically valid for \~15 minutes (enforced by S3). Consumers should fetch the archive immediately\
> rather than storing the URL.\
> \
> AI guidance:\
> \- This is not the same as flow execution logs — use \`GET /v1/flows/{\_id}/jobs/{\_jobId}/logs\` for step-level\
> &#x20; execution logs.\
> \- If the job has no diagnostics (very recent jobs, or jobs whose artifacts have been purged after\
> &#x20; \`purgeAt\`), the response may be empty — check for a \`signedURL\` field before attempting download.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JobDiagnosticsResponse":{"allOf":[{"$ref":"#/components/schemas/JobFilesSignedUrlResponse"},{"type":"object","description":"Signed URL response for downloading diagnostics for a job."}]},"JobFilesSignedUrlResponse":{"type":"object","description":"Signed URL response for downloading job files.","properties":{"signedURL":{"type":["string","null"],"description":"A single signed URL (when only one file is returned)."},"signedURLs":{"type":"array","description":"Multiple signed URLs (when multiple files are returned).","items":{"type":"string"}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/jobs/{_id}/diagnostics":{"get":{"operationId":"getJobDiagnostics","tags":["Jobs"],"summary":"Get a signed URL for job diagnostics","description":"Returns a short-lived S3 pre-signed URL pointing to a diagnostic archive (`.zip`) for the given job. The\narchive contains server-side traces/logs that Celigo support uses to debug execution failures.\n\nThe URL is typically valid for ~15 minutes (enforced by S3). Consumers should fetch the archive immediately\nrather than storing the URL.\n\nAI guidance:\n- This is not the same as flow execution logs — use `GET /v1/flows/{_id}/jobs/{_jobId}/logs` for step-level\n  execution logs.\n- If the job has no diagnostics (very recent jobs, or jobs whose artifacts have been purged after\n  `purgeAt`), the response may be empty — check for a `signedURL` field before attempting download.","parameters":[{"name":"_id","in":"path","required":true,"description":"Job id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Signed URL for the diagnostics archive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobDiagnosticsResponse"}}}},"204":{"description":"No diagnostics available for this job (archive may be absent or purged)."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get the most recent job(s) for a flow

> Returns the most recent job record(s) for the given flow. Typically one entry (the latest flow run), though\
> the platform may include related retry jobs depending on account configuration.\
> \
> AI guidance:\
> \- Use this to answer "when did this flow last run and what was the outcome?" without having to search\
> &#x20; \`GET /v1/jobs\`.\
> \- For a richer parent+children view, feed the returned \`\_id\` into \`GET /v1/jobs/{\_id}/family\`.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers **summary projection** on supported list endpoints: the server\nreturns a minimal identity set for each record (`_id`, `name`, plus a\nresource-specific always-on set like `adaptorType` on exports/imports,\nor richer defaults on `ashares`, `audit`, `httpconnectors`, `transfers`,\netc.) and adds any listed fields that exist on the record. Listed fields\nthe record doesn't carry are silently dropped.\n\nDot notation is supported for projecting nested sub-fields — e.g.\n`include=ftp.directoryPath` on `/v1/exports` returns just that nested\nfield inside `ftp` for FTP-type exports (and omits `ftp` entirely for\nnon-FTP exports).\n\nRules:\n- Value regex is `{a-z A-Z . _}` (letters, dots, underscores) plus the\n  comma separator; digits are also accepted in practice. Any other\n  character returns **400 `invalid_query_params`**.\n- Empty value (`include=`) or bare `include` is ignored — the full\n  default record is returned.\n- `include` and `exclude` are **mutually exclusive**. Passing both\n  returns **400 `invalid_query_params`**: *\"Please provide either\n  include or exclude param in the request query and not both.\"*\n- Array-bracket syntax (`include[]=...`) is not supported and can return\n  a 500.\n- Only list endpoints honor projection — on GET-by-id the parameter is\n  silently ignored.\n- A small set of list endpoints explicitly reject both `include` and\n  `exclude` with **400 `invalid_query_params`** and a message of the form\n  *\"Include or exclude query params are not applicable for `<resource>`\n  resource.\"* Known rejections: `/v1/ediprofiles`, `/v1/environments`,\n  `/v1/iClients`, `/v1/lookupcaches`, `/v1/tags`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to remove from the default response on\nsupported list endpoints. Unlike `include`, `exclude` does NOT trigger\nsummary projection — callers get the standard full-record shape with the\nnamed fields stripped out.\n\nRules:\n- Value regex is `{a-z A-Z . _}` (letters, dots, underscores) plus the\n  comma separator; digits are also accepted in practice. Any other\n  character returns **400 `invalid_query_params`**.\n- Empty value (`exclude=`) is ignored.\n- Certain protected identity fields **cannot be stripped** — e.g.\n  `exclude=name` on `/v1/exports` is silently ignored and `name` remains\n  in the response. Protected sets vary per resource.\n- `include` and `exclude` are **mutually exclusive**. Passing both\n  returns **400 `invalid_query_params`**: *\"Please provide either\n  include or exclude param in the request query and not both.\"*\n- Only list endpoints honor stripping — on GET-by-id the parameter is\n  silently ignored.\n- A small set of list endpoints explicitly reject both `include` and\n  `exclude` with **400 `invalid_query_params`** and a message of the form\n  *\"Include or exclude query params are not applicable for `<resource>`\n  resource.\"* Known rejections: `/v1/ediprofiles`, `/v1/environments`,\n  `/v1/iClients`, `/v1/lookupcaches`, `/v1/tags`.","schema":{"type":"string"}}},"schemas":{"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/flows/{_id}/jobs/latest":{"get":{"operationId":"getLatestFlowJobs","tags":["Jobs"],"summary":"Get the most recent job(s) for a flow","description":"Returns the most recent job record(s) for the given flow. Typically one entry (the latest flow run), though\nthe platform may include related retry jobs depending on account configuration.\n\nAI guidance:\n- Use this to answer \"when did this flow last run and what was the outcome?\" without having to search\n  `GET /v1/jobs`.\n- For a richer parent+children view, feed the returned `_id` into `GET /v1/jobs/{_id}/family`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Flow id.","schema":{"type":"string","format":"objectId"}},{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"responses":{"200":{"description":"Most recent job(s) for the flow. May be a single-element array.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Job"}}}}},"204":{"description":"The flow has no recorded runs."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get the most recent job(s) for an integration

> Returns the most recent job record(s) across all flows in the given integration. Useful for a top-level\
> "is anything running / did anything just fail?" check on an integration tile.\
> \
> AI guidance:\
> \- Prefer this over calling \`getLatestFlowJobs\` per flow when summarizing the whole integration.\
> \- The result is not filtered by status — inspect each entry's \`status\` to distinguish success from failure.

```json
{"openapi":"3.1.0","info":{"title":"Jobs","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Job":{"type":"object","description":"A job represents one execution of a flow/export/import (or a retry) in integrator.io.\nJobs are primarily read-only records created by the platform when executions occur.\n","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Job id."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Owner user id for the job."},"type":{"type":"string","readOnly":true,"description":"Job type.\n- `flow`: a flow run (parent job)\n- `export` / `import`: child jobs for an export/import step\n- `retry` / `bulk_retry`: error management retries\n","enum":["export","import","flow","retry","bulk_retry"]},"status":{"type":"string","readOnly":true,"description":"Current job status.","enum":["queued","running","retrying","completed","failed","canceled","canceling"]},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration id this job belongs to (if applicable)."},"_flowId":{"type":"string","format":"objectId","readOnly":true,"description":"Flow id this job belongs to (if applicable)."},"_exportId":{"type":"string","format":"objectId","readOnly":true,"description":"Export id. Present on child export jobs and also on parent flow\njobs (where it references the first page-generator export)."},"_importId":{"type":"string","format":"objectId","readOnly":true,"description":"Import id for import child jobs (if applicable)."},"_expOrImpId":{"type":"string","format":"objectId","readOnly":true,"description":"Internal reference to an export/import for branched flows (if applicable)."},"_retryOfJobId":{"type":"string","format":"objectId","readOnly":true,"description":"If this is a retry job, the original job id being retried."},"_flowJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent flow job id (for child jobs)."},"_parentJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Parent job id (used for branched flows / hierarchy)."},"_bulkJobId":{"type":"string","format":"objectId","readOnly":true,"description":"Bulk retry parent job id (if applicable)."},"startedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution started."},"endedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When execution ended."},"resolvedAt":{"type":"string","format":"date-time","readOnly":true,"description":"When errors for the job were fully resolved (if applicable)."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job record was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Last modification time for the job record."},"lastExecutedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Last time the job executed work (may differ from createdAt/startedAt)."},"purgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from primary storage."},"clickhousePurgeAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the job should be purged from ClickHouse (if enabled)."},"triggeredBy":{"type":"string","readOnly":true,"description":"Who/what triggered the job (free-form string)."},"canceledBy":{"type":"string","readOnly":true,"description":"Who/what requested cancellation (free-form string)."},"flowExecutionGroupId":{"type":"string","readOnly":true,"description":"Groups multiple related jobs for a single flow execution."},"numError":{"type":"integer","readOnly":true,"description":"Total number of errors produced by the job (including resolved ones).\nUse `numOpenError` for the count of currently unresolved errors.\n"},"numOpenError":{"type":"integer","readOnly":true,"description":"Number of unresolved errors (equivalent to `numError - numResolved`).\nThis is the value dashboards surface as \"errors needing attention.\"\n"},"numResolved":{"type":"integer","readOnly":true,"description":"Number of resolved errors."},"numResolvedByAdaptor":{"type":"integer","readOnly":true,"description":"Number of errors resolved by the adaptor."},"numSuccess":{"type":"integer","readOnly":true,"description":"Number of successful records/pages."},"numIgnore":{"type":"integer","readOnly":true,"description":"Number of ignored records/pages."},"numExport":{"type":"integer","readOnly":true,"description":"Legacy field used by retry logic. May be deprecated.\n"},"numPagesGenerated":{"type":"integer","readOnly":true,"description":"Number of pages generated by an export/page generator."},"doneExporting":{"type":"boolean","readOnly":true,"description":"Whether export/page generation is complete."},"numPagesProcessed":{"type":"integer","readOnly":true,"description":"Number of pages processed by downstream imports."},"oIndex":{"type":"integer","readOnly":true,"description":"Branch/router index for branched flows (if applicable)."},"retriable":{"type":"boolean","readOnly":true,"description":"Whether this job is eligible for retry."},"files":{"type":"array","readOnly":true,"description":"Files produced by the job (may be empty).","items":{"$ref":"#/components/schemas/JobFileRef"}},"logs":{"type":"array","readOnly":true,"description":"Log artifacts associated with the job (may be empty).","items":{"$ref":"#/components/schemas/JobLogRef"}},"errorFile":{"allOf":[{"$ref":"#/components/schemas/JobErrorFileRef"},{"description":"Error file artifact (if any)."}]},"logMode":{"type":"string","readOnly":true,"description":"Effective logging mode used for this job (derived from flow + account settings)."},"__lastPageGeneratorJob":{"type":"boolean","readOnly":true,"description":"Internal flag used by the UI for page-generator job handling."}}},"JobFileRef":{"type":"object","description":"Reference to a file produced by a job.","properties":{"id":{"type":"string","description":"File id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite","s3"]},"name":{"type":"string","description":"Display name for the file (if available)."}}},"JobLogRef":{"type":"object","description":"Reference to a job log artifact.","properties":{"id":{"type":"string","description":"Log id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["netsuite"]}}},"JobErrorFileRef":{"type":"object","description":"Reference to an error file produced by a job.","properties":{"id":{"type":"string","description":"Error file id in the underlying storage provider."},"host":{"type":"string","description":"Storage host/provider.","enum":["s3"]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/jobs/latest":{"get":{"operationId":"getLatestIntegrationJobs","tags":["Jobs"],"summary":"Get the most recent job(s) for an integration","description":"Returns the most recent job record(s) across all flows in the given integration. Useful for a top-level\n\"is anything running / did anything just fail?\" check on an integration tile.\n\nAI guidance:\n- Prefer this over calling `getLatestFlowJobs` per flow when summarizing the whole integration.\n- The result is not filtered by status — inspect each entry's `status` to distinguish success from failure.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Most recent job(s) for the integration.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Job"}}}}},"204":{"description":"The integration has no recorded runs."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.celigo.com/api/api-reference/jobs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
