Bellwork
OpportunitiesIdRefresh

Read an opportunity's verification verdict

The stored verdict. Poll this after a POST returns 202. TWO independent verdicts, and acting on one alone will burn your reps: `verification_status` — does the CLAIM still hold? `window_status` — is there still a chance to ACT? They fail independently. A procurement page describes its bid accurately for months after the deadline passes, so a row can be `confirmed` and `closed` at the same time — the claim is true and the opportunity is dead. Treat `confirmed` + (`open` | `closing` | `durable`) as live, and nothing else. `durable` means there is nothing to expire (a standing staffing gap, an adopted law). `unreachable` means we could not settle it — unconfirmed, never confirmed. `verifying` means a run is still going.

GET
/opportunities/{id}/refresh

The stored verdict. Poll this after a POST returns 202.

TWO independent verdicts, and acting on one alone will burn your reps:

verification_status — does the CLAIM still hold? window_status — is there still a chance to ACT?

They fail independently. A procurement page describes its bid accurately for months after the deadline passes, so a row can be confirmed and closed at the same time — the claim is true and the opportunity is dead. Treat confirmed + (open | closing | durable) as live, and nothing else.

durable means there is nothing to expire (a standing staffing gap, an adopted law). unreachable means we could not settle it — unconfirmed, never confirmed. verifying means a run is still going.

AuthorizationBearer <token>

API key (sk_live_... prefix). Generate keys in the UI under Settings > API Keys, then send it as Authorization: Bearer sk_live_...

In: header

Path Parameters

id*string

Opportunity id

Formatuuid

Response Body

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/opportunities/497f6eca-6276-4993-bfeb-53cbbbba6f08/refresh"
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "verification_status": "unverified",
  "verification_note": "string",
  "last_verified_at": "string",
  "window_status": "unknown",
  "window_ends_on": "string",
  "source_checks": [
    {
      "url": "string",
      "checked_at": "string",
      "status": "ok",
      "note": "string"
    }
  ]
}
{
  "error": "string",
  "message": "string",
  "statusCode": -9007199254740991
}
Empty
Empty
{
  "error": "string",
  "message": "string",
  "statusCode": -9007199254740991
}

List opportunities GET

Agent-produced, verified sales opportunities for the caller's projects. There is no review gate: an opportunity is visible to its owner the moment the agent writes it. An opportunity is written once from a signal and is NOT re-verified on its own, so a vacancy can since have been filled. Read `verification_status` and `last_verified_at` before acting on a row, and call POST /opportunities/{id}/refresh to re-check it. A row that has never been re-checked reports `verification_status: "unverified"` and a null `last_verified_at` rather than implying freshness. Each row carries the team's `verdict` from /opportunities/verdicts — acted on (`pursued`), set aside (`dismissed`) or `not_useful` — or null when nothing is filed (open). `verdict` filters on it in the query, so totals and pages are the filtered set.

Start a check on whether an opportunity is still live POST

Runs a research agent against one opportunity: re-reads its sources, looks the record up in Bellwork's procurement corpus where relevant, and searches for current evidence. Intended to be called once per row as it crosses into a CRM, and again by hand later — there is no background re-verification sweep. ASYNCHRONOUS. Returns 202 with a `poll` URL; GET the same path for the verdict. Runs take tens of seconds because establishing a bid's real close date can take several searches. A verdict from the last 6 hours is returned immediately (200, `started: false`) unless `force=true`. The verdict has TWO parts and callers must read both — see the GET response.