Getting started
The Prokure API gives you programmatic access to the opportunities Prokure has matched for your company, along with the reasoning behind each match.
Who this is for
Section titled “Who this is for”These docs are for Prokure customers who want to pull matched opportunities into their own systems — a CRM, a bid-tracking board, an internal dashboard, or an AI agent.
Generate an API key
Section titled “Generate an API key”-
Sign in to the portal at app.prokure.ca.
-
Go to Settings → API keys.
-
Create a key, give it a name, and select the scopes it needs. See Authentication & API keys for what each scope grants.
-
Copy the secret. It starts with
pk_live_and is shown exactly once — Prokure stores only a hash of it, so there is no way to recover it later. If you lose it, revoke the key and create another.
Your first request
Section titled “Your first request”Every request authenticates with the key in an Authorization: Bearer header.
curl https://app.prokure.ca/api/v1/opportunities \ -H "Authorization: Bearer pk_live_YOUR_KEY_HERE"const response = await fetch("https://app.prokure.ca/api/v1/opportunities", { headers: { Authorization: `Bearer ${process.env.PROKURE_API_KEY}` },});
if (!response.ok) { throw new Error(`Prokure API returned ${response.status}`);}
const { items, nextCursor } = await response.json();import osimport httpx
response = httpx.get( "https://app.prokure.ca/api/v1/opportunities", headers={"Authorization": f"Bearer {os.environ['PROKURE_API_KEY']}"},)response.raise_for_status()
payload = response.json()items, next_cursor = payload["items"], payload["nextCursor"]That request needs the opportunities:read scope.
What comes back
Section titled “What comes back”A successful response is a page of opportunities plus a cursor. One item is
shown here; a real page carries up to limit of them.
{ "items": [ { "id": "7c2f4e8a-3b91-4d5e-9a0c-1f6b8d2e4a73", "rfp_id": "b41d9e07-52c8-4a16-8f3d-0c7e5a9b2d64", "title": "Supply and delivery of portable field radios", "issuing_body": "Regional Health Authority", "source": "email_alert", "deadline": "2026-09-15T19:00:00.000Z", "estimated_value": null, "score": 82, "score_source": "pdf_verdict", "status": "notified", "archived_at": null, "product_match_name": "Field Radio Kit 400 Series", "discovered_at": "2026-08-18T13:04:22.117Z" } ], "nextCursor": "eyJzb3J0VmFsdWUiOiI4MiIsIm1hdGNoSWQiOiI3YzJmNGU4YS0zYjkxLTRkNWUtOWEwYy0xZjZiOGQyZTRhNzMifQ"}A few fields worth knowing before you build against them:
idis the opportunity,rfp_idis the underlying solicitation. Every other opportunity endpoint takes theid.score_sourcetells you what the score was computed from:pdf_verdictwhen Prokure read the solicitation documents,metadata_verdictwhen it had only the notice text, ordimensionalfor a score that predates the current verdict model.estimated_valueis usuallynull. None of the portal feeds publish a contract value, so it is only populated when the value appeared in text Prokure could parse.nextCursoris an opaque string. Pass it straight back as thecursorquery parameter to get the next page; do not parse it or construct one yourself. It isnullon the last page.
Listing options
Section titled “Listing options”GET /api/v1/opportunities accepts these query parameters:
| Parameter | Type | Default | Notes |
|---|---|---|---|
status |
string, repeatable | — | One of scored, screened, notified, draft_requested, draft_sent, approved, archived. Repeat the parameter to pass several. |
q |
string, 1–200 chars | — | Free-text search. |
source |
string, 1–40 chars | — | Restrict to one discovery source. |
deadline_before |
ISO 8601 date-time | — | |
deadline_after |
ISO 8601 date-time | — | |
min_score |
number, 0–100 | — | |
sort |
score, deadline, or discovered_at |
score |
|
cursor |
string, up to 300 chars | — | The nextCursor from the previous page. |
limit |
integer, 1–100 | 25 |
Page size. |
status=archived cannot be combined with any other status — archived is its own
view, not a filter that stacks. Sending both returns 400 validation_failed.
Where to go next
Section titled “Where to go next”- Authentication & API keys — key lifecycle and what each scope grants.
- API reference — every endpoint, generated from the OpenAPI document.
- Rate limits & errors — the per-route limits and the error body shape.
- Best practices — key storage, retries, and polling.