Authentication

Generate an API key from Settings → Developers → API keys. Pass it as a Bearer token in every request:

curl https://api.reconnaissance-ai.com/v1/contacts \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxx" \
  -H "Accept: application/json"

Base URL: https://api.reconnaissance-ai.com/v1
Rate limit: 60 req/min on Pro · 600 req/min on Enterprise
Encoding: JSON (Content-Type: application/json)

Endpoints

GET /v1/contacts

List contacts in your workspace. Supports limit, cursor, and filter by pipeline_stage, icp_score_min.

{
  "data": [
    {
      "id": "c_4f3e...",
      "name": "Marcus König",
      "email": "marcus@physical.ai",
      "company": "Physical Intelligence",
      "role": "Head of ML",
      "icp_score": 87,
      "pipeline_stage": "contacted",
      "intent_band": "hot"
    }
  ],
  "next_cursor": "eyJpZCI6ImNfNGYzZSJ9"
}
POST /v1/contacts

Upsert a contact. Match by email or crm_id. Creates if missing, updates otherwise.

POST /v1/contacts
{
  "email": "marcus@physical.ai",
  "name": "Marcus König",
  "company": "Physical Intelligence",
  "role": "Head of ML"
}
GET /v1/signals

List active signals across your workspace. Filter by type, contact_id, since (ISO 8601), min_weight.

{
  "data": [
    {
      "id": "s_8a2b...",
      "type": "funding_detected",
      "contact_id": "c_4f3e...",
      "company": "Physical Intelligence",
      "weight": 20,
      "fired_at": "2026-04-15T09:22:11Z",
      "metadata": { "round": "Series B", "amount_usd": 400000000 }
    }
  ]
}
GET /v1/research/{contact_id}

Fetch the AI research brief for a contact — company summary, products, tech stack, pain points, industry tag.

POST /v1/outreach/generate

Generate outreach for a contact. Optionally pin an angle (trigger / problem / insight / competitor) and a template.

POST /v1/outreach/generate
{
  "contact_id": "c_4f3e...",
  "angle": "auto",
  "email_steps": 3,
  "linkedin_steps": 1
}

→ 200 OK
{
  "email_1": { "subject": "...", "body": "..." },
  "email_2": { "subject": "...", "body": "..." },
  "email_3": { "subject": "...", "body": "..." },
  "linkedin": { "connection": "...", "msg_1": "...", "msg_2": "...", "msg_3": "..." },
  "resolved_angle": "competitor",
  "hook_archetype": "timeline"
}
POST /v1/webhooks/register

Register a webhook for events. Available events: signal.fired, reply.received, pipeline_stage.changed, research.completed.

POST /v1/webhooks/register
{
  "url": "https://your-app.com/hooks/recon",
  "events": ["signal.fired", "reply.received"],
  "secret": "whsec_..."
}
GET /v1/usage

Current billing period usage — AI generations, API calls, active seats.

Error codes

StatusError codeMeaning
400invalid_requestMalformed JSON or missing required field
401invalid_tokenMissing or invalid Bearer token
403feature_not_availableEndpoint requires Pro or Enterprise plan
404not_foundResource doesn't exist or you don't have access
429rate_limitedToo many requests. Retry after the Retry-After header
500internal_errorSomething broke on our side. We're on it (Sentry'd)
SDKs

Official SDKs for JavaScript / TypeScript and Python are on the roadmap. For now, any HTTP client works. A typed OpenAPI schema is available at https://api.reconnaissance-ai.com/openapi.json.

Early API access

Building on top of us?

Drop us a line and we'll get you API keys, SDK preview access, and a Slack channel with the engineers building the endpoints you'll use.