> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coverbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Triggering workflows from external systems

> Three patterns for starting work in Coverbase from outside the UI.

<div className="sr-only">For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt) — this page is also available in markdown by appending .md to the URL.</div>

The most common integration question is whether an external system can start work in Coverbase without anyone touching the UI. Yes. There are three patterns.

## Pattern 1: Create the object, let triggers handle the rest

Most workflows are bound to object events. The cleanest integration is to bring the object into Coverbase and let the workflow engine react.

Vendor and service creation is **not** part of the resource API documented here — vendors enter Coverbase through the dashboard or the [Import API](/import-api), which is a separate integration surface. Once a vendor is created, a workflow bound to the `Vendor.Created` trigger runs: conditions inspect the imported attributes, classify the vendor, and the workflow can launch an assessment, send a questionnaire, and notify the internal owner with no UI interaction.

Use this pattern when the work maps naturally onto an object lifecycle. Use Pattern 2 or 3 when you need to start work explicitly against an existing object.

## Pattern 2: Explicitly start an assessment

When an external system needs to start an assessment on an existing vendor, for example a GRC tool beginning annual reassessment of a known vendor, it can call the assessments endpoint directly.

```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/assessments" \
  -H "Authorization: Bearer ak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
    "control_set_ids": ["cbctst_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071"],
    "service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"],
    "trigger_workflow": "annual-reassessment-flow"
  }'
```

The `trigger_workflow` parameter is optional. If specified, that named workflow is started alongside the assessment (a `404 workflow_not_found` is returned if no workflow with that name exists for the org). See the [Assessments API](/api-reference/assessments) for the full request and response schema.

## Pattern 3: Invoke a named workflow directly

For cases that don't map cleanly to a single object event, for example sending the standard data privacy questionnaire to forty vendors and aggregating responses into a quarterly report, external systems can invoke a workflow by name and pass it parameters.

```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/workflows/quarterly-privacy-sweep/run" \
  -H "Authorization: Bearer ak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "vendor_filter": { "tags": ["processes_pii"] },
      "due_date": "2026-06-30"
    }
  }'
```

The response includes a `workflow_run_id` you can poll with `GET /v1/workflows/runs/{id}`.

```json theme={null}
{
  "workflow_run_id": "cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b",
  "workflow_name": "quarterly-privacy-sweep",
  "status": "started",
  "started_at": 1746576000,
  "input": { "vendor_filter": { "tags": ["processes_pii"] }, "due_date": "2026-06-30" }
}
```

See the [Workflows API](/api-reference/workflows) for the full schema.

## Idempotency

`POST /v1/assessments` and `POST /v1/workflows/{name}/run` accept an `Idempotency-Key` header. If the same key is replayed within 24 hours for that endpoint, the original response body is returned and no new run is started. Full behavior is documented in [API conventions → Idempotency](/conventions#idempotency).

```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/workflows/onboard-vendor/run" \
  -H "Authorization: Bearer ak_live_xxx" \
  -H "Idempotency-Key: ariba-req-7821" \
  -H "Content-Type: application/json" \
  -d '{ "input": {} }'
```

<Tip>
  Use an identifier from the source system (a procurement request ID, a ticket number) as the idempotency key. That way retries from the source system are naturally deduplicated without extra bookkeeping on your side.
</Tip>
