Jobs

Jobs are the mechanism behind asynchronous operations in the v5 API. Endpoints that kick off long-running work (like watchlist rescreens) return a jobId immediately and run the actual work in the background. Use the jobs endpoint to poll for status.

Overview

When you call an endpoint that starts an asynchronous operation, it doesn't wait for the work to finish. Instead, it:

  1. Writes a job run record describing what should happen.
  2. Returns { triggered: true, jobId } to the caller — typically within a second.
  3. A background listener picks up the job, runs the work, and writes lifecycle status (running → completed or failed) to the job's result.

To observe what happened, poll GET /v5/verifications/:trace/jobs/:type/:jobId.

Why asynchronous?

Screening and risk cascades fan out to multiple provider calls (one per stakeholder, plus one for the entity). On a large KYB verification this can take tens of seconds — longer than a reasonable HTTP request lifetime. Running them asynchronously means:

  • Callers get immediate acknowledgement; no long-held HTTP connections.
  • Partial failures (e.g. one stakeholder's Dilisense call times out) don't break the whole operation. Other steps keep running.
  • Retries are automatic and bounded — see Retries below.

Job types

TypeWritten byRuns
watchlistPOST /v5/verifications/:trace/watchlistFull watchlist screening + risk recalculation cascade

More types will be added as new asynchronous operations are built. Each type has its own gate, run history, and listener.

Statuses

StatusTerminal?Meaning
pendingnoJob has been written but the listener has not started it yet.
runningnoThe listener has claimed the run and is executing the handler.
completedyesHandler finished successfully. The operation's side effects (e.g. new screening documents) are committed.
failedyesHandler threw. See errorSummary for a one-line description. To re-run the operation, dispatch a new job.
rejectedyesAnother run of the same type was already in-flight when this one tried to claim the gate. See conflictingJobId to find the active run.

Treat completed, failed, and rejected as stop signals when polling.

Debounce

Each job type has a gate — only one run of that type can be in-flight per verification at a time. If you call a job-dispatching endpoint while a previous run is still running, you'll receive a 429 Too Many Requests with the conflicting job's ID so you can poll that one instead.


GET/v5/verifications/:trace/jobs/:type/:jobId

Get job status

Retrieve the run record and lifecycle result for a specific job. Use this to poll after a dispatch endpoint returns a jobId.

Path parameters

  • Name
    trace
    Type
    string
    Description

    The verification trace that owns this job.

  • Name
    type
    Type
    string
    Description

    The job type (e.g. watchlist).

  • Name
    jobId
    Type
    string
    Description

    The job ID returned by the dispatch endpoint.

Response fields

The data field contains two objects: run (the immutable dispatch record) and result (the mutable lifecycle state).

  • Name
    run.jobId
    Type
    string
    Description

    Matches the path parameter.

  • Name
    run.type
    Type
    string
    Description

    The job type.

  • Name
    run.payload
    Type
    object
    Description

    Type-specific input data for the operation. Empty for watchlist.

  • Name
    run.requestedAt
    Type
    number
    Description

    Epoch milliseconds when the job was dispatched.

  • Name
    run.sourceAction
    Type
    string
    Description

    One of manual-api, manual-portal, manual-admin, scheduled, system.

  • Name
    run.sourceUid
    Type
    string
    Description

    UID of the user/service that dispatched the job (optional).

  • Name
    run.sourceEmail
    Type
    string
    Description

    Email of the operator (optional; present on portal/admin flows).

  • Name
    result.status
    Type
    string
    Description

    See the Statuses table.

  • Name
    result.attemptCount
    Type
    number
    Description

    Number of listener invocations that have claimed this run.

  • Name
    result.startedAt
    Type
    number
    Description

    Epoch milliseconds when the listener claimed the run (set once running).

  • Name
    result.completedAt
    Type
    number
    Description

    Epoch milliseconds when the run reached a terminal status.

  • Name
    result.errorSummary
    Type
    string
    Description

    Short human-readable error description (set when status is failed).

  • Name
    result.conflictingJobId
    Type
    string
    Description

    The run holding the gate (set when status is rejected).

Error responses

Status CodeError TypeDescription
404not_foundThe job does not exist.
422validation_errorUnknown job type or empty jobId.

Request

GET
/v5/verifications/:trace/jobs/:type/:jobId
curl -X GET "https://api.bronid.com/v5/verifications/{trace}/jobs/watchlist/{jobId}" \
  -H "Authorization: Basic {credentials}"

Response — completed

{
  "timestamp": "2026-02-28T04:00:05.000Z",
  "serviceUid": "5qA5Hq0n1JQTY2TASItxYXSRyND3",
  "trace": "abc123-verification-trace",
  "path": "/v5/verifications/:trace/jobs/:type/:jobId",
  "pathParams": {
    "trace": "abc123-verification-trace",
    "type": "watchlist",
    "jobId": "V1StGXR8_Z5jdHi6B-myT"
  },
  "statusCode": 200,
  "message": "Job retrieved.",
  "help": null,
  "status": "success",
  "data": {
    "run": {
      "jobId": "V1StGXR8_Z5jdHi6B-myT",
      "type": "watchlist",
      "payload": {},
      "requestedAt": 1740715200000,
      "sourceAction": "manual-api"
    },
    "result": {
      "jobId": "V1StGXR8_Z5jdHi6B-myT",
      "type": "watchlist",
      "status": "completed",
      "attemptCount": 1,
      "startedAt": 1740715200120,
      "completedAt": 1740715203400
    }
  },
  "error": null
}

Response — failed

{
  "statusCode": 200,
  "status": "success",
  "data": {
    "run": { "...": "..." },
    "result": {
      "jobId": "V1StGXR8_Z5jdHi6B-myT",
      "type": "watchlist",
      "status": "failed",
      "attemptCount": 1,
      "errorSummary": "Job execution failed",
      "completedAt": 1740715230000
    }
  }
}

Was this page helpful?