The leads API reads your workspace's opportunities over HTTP: each business Proxi found, why to reach out now, the public record behind it, the people to contact, and a letter ready to send. It is read only. Use it to pull leads into your CRM, a letter service or your own scripts.
Send your key in the X-Proxi-API-Key header on every request.
X-Proxi-API-Key: <your key from Settings>
Create a key in the app under Settings > API access. A key belongs to one workspace and can only read: it never sends, approves or spends anything. Keep it in a secret store and revoke it there if it leaks.
Base URL: https://getproxi.ai/db/api/v1
One page of the workspace's opportunities, oldest change first (by updated_at, then id). Withdrawn opportunities are still returned with withdrawn_at set, so you learn when one is taken back.
| Parameter | Type | Description |
|---|---|---|
limit | integer | Rows per page, 1 to 100. Default 50. |
cursor | string | The next_cursor from the previous page. Opaque. |
updated_after | date-time | ISO 8601 with a time zone. Only rows changed after this instant. |
motion | enum | private_retrofit, partner_package, named_account, warm_visit |
disposition | enum | act_now, qualify, research, watch, reject |
One opportunity by its id (a UUID), in the same shape as a list item. An unknown id and another workspace's id both answer 404.
curl -sS -H "X-Proxi-API-Key: $PROXI_API_KEY" \
"https://getproxi.ai/db/api/v1/opportunities?limit=1&disposition=act_now"
{
"items": [
{
"id": "3f2a9c1e-0000-4000-8000-000000000001",
"version": 3,
"business_id": "8b7d6e5f-0000-4000-8000-000000000002",
"title": "Hangar expansion at Example Air Services",
"motion": "warm_visit",
"disposition": "act_now",
"action_kind": "visit",
"is_net_new_account": true,
"company": {
"name": "Example Air Services LLC",
"website": "https://example.com",
"phone": "+1 555 010 0100",
"email": "office@example.com",
"address": "100 Airport Rd, Springfield, IL 62701",
"map_url": "https://www.openstreetmap.org/?mlat=39.80&mlon=-89.64",
"logo_url": "https://example.com/logo.png",
"state": "IL"
},
"why_reach_out": "Filed a building permit for a 12,000 sq ft hangar on Oct 30.",
"record": { "...": "the public record behind this lead" },
"mechanical_scope": "New hangar HVAC and compressed air",
"procurement_state": "planning",
"next_question": "Who is specifying the mechanical package?",
"route": { "description": "Ask the GC named on the permit", "relationship_source_ids": ["src_1"], "role_verified": false },
"unknowns": ["mechanical contractor not named"],
"evidence": [
{ "source_id": "src_1", "url": "https://example.gov/permits/12345", "locator": null, "claim": "Permit 12345 issued for hangar construction", "published_at": null, "event_date": "2026-10-30", "retrieved_at": "2026-11-01T14:02:00Z", "visibility": "public", "snapshot_id": null }
],
"counterevidence": [],
"contacts": [
{ "id": "c_1", "name": "Jordan Lee", "role": "Facilities Manager", "relationship_to_project": "buyer", "email": "jordan@example.com", "email_source": "printed", "phone": "+1 555 010 0101", "phone_kind": "direct", "address": null, "address_type": "unknown", "source_ids": ["src_1"], "verified_at": null, "export_policy": "allowed", "deliverability_verified": false }
],
"letter": { "subject": "Your hangar project on Airport Rd", "body": "Hi Jordan, ..." },
"ranking_score": 82,
"updated_at": "2026-11-07T15:30:00Z",
"recheck_due_at": "2026-11-21T00:00:00Z",
"withdrawn_at": null
}
],
"next_cursor": "eyJ1IjoiMjAyNi0xMS0wN1QxNTozMDowMFoifQ",
"snapshot_as_of": "2026-11-08T12:00:00Z"
}
| Field | Type | Description |
|---|---|---|
id | uuid | Stable across versions of the same opportunity. |
version | integer | Goes up each time the opportunity changes. |
business_id | uuid | The business this opportunity is about. facility_id, project_id and package_id are set when known, else null. |
title | string or null | Short headline. |
motion | enum | How to pursue it. See the list parameters. |
disposition | enum | The desk's call. act_now means the next action is ready, not that equipment is open to buy. |
action_kind | enum or null | introduction, qualification, visit, rfq, research, watch |
is_net_new_account | boolean | False for a business you already work with. |
company | object | The business: name, website, phone, email, address, map_url, logo_url, state. Any part may be null. |
why_reach_out | string or null | One plain sentence on why to contact them now. |
record | object or null | The public record the opportunity was read from. |
mechanical_scope | string or null | The equipment or work in scope. |
procurement_state | enum | not_established, planning, supplier_inquiry, open_package_confirmed, supplier_selected, ordered, installed, withdrawn, unknown |
next_question | string or null | The one question to ask. |
route | object or null | description (who can answer and how to reach them), relationship_source_ids, role_verified (true only when the role was read on a page). |
unknowns | string[] | What the record does not say yet. |
evidence, counterevidence | object[] | Each: source_id, url, locator, claim, published_at, event_date, retrieved_at, visibility (public or tenant_private), snapshot_id. |
contacts | object[] | Each: id, name, role, relationship_to_project, email, email_source, phone, phone_kind, address, address_type, source_ids, verified_at, export_policy, deliverability_verified. |
contacts[].email_source | enum or null | printed (read on a public page) or finder (from an email finder). |
contacts[].export_policy | enum | allowed, redacted or restricted. Email, phone and address are null unless allowed. |
contacts[].phone_kind | enum | direct, switchboard, branch, unknown |
letter | object or null | A ready letter: subject and body. |
ranking_score | number or null | 0 to 100. A priority heuristic, never a win probability. |
updated_at | date-time | Last change. |
recheck_due_at | date-time or null | When Proxi will look at it again. |
withdrawn_at | date-time or null | Set when the opportunity was taken back. |
Pass each page's next_cursor as cursor until it comes back null. To pick up changes later, keep snapshot_as_of from your last page and send it as updated_after on your next poll. The snapshot is taken 30 seconds before the page, so a row that changed while you were paging is not skipped.
curl -sS -H "X-Proxi-API-Key: $PROXI_API_KEY" \
"https://getproxi.ai/db/api/v1/opportunities?updated_after=2026-11-08T12:00:00Z"
Every error has the same body. Every response carries an X-Request-Id header; quote it when reporting a problem.
{ "code": "rate_limited", "message": "Too many requests.", "request_id": "req_abc123", "retryable": true, "retry_after_seconds": 12 }
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_parameter, invalid_cursor | A query parameter or cursor could not be read. |
| 401 | missing_key, invalid_key | No key, or the key is malformed, unknown, expired or revoked. |
| 403 | insufficient_scope, workspace_not_active | The key cannot read this, or the workspace is not active. |
| 404 | not_found | No such opportunity in your workspace. |
| 429 | rate_limited | Over the rate limit. Wait retry_after_seconds (also sent as Retry-After). |
| 503 | unavailable | Temporarily unavailable. Retry with backoff. |
60 requests a minute per key. The 61st answers 429 with Retry-After.
Pull each act_now opportunity's letter and contacts into a letter or mail service, push company and why_reach_out into your CRM, or post new leads to a team channel on every poll.