Markdown for agents
This page as plain markdown, ready to paste into an LLM.
Meta
Two endpoints that need no scope and answer what this key is and what the API accepts.
Who this key is, what it may do, which workspaces it currently reaches
curl -sS https://api.leadarc.io/v1/me \
-H "Authorization: Bearer $LEADARC_API_KEY"No scope required. Every integration should call this first. It is the discovery endpoint, and it is the only place the API tells a caller what the API will let it do.
Response:
{
"object": "me",
"key": {
"id": "k7m2p9qh",
"name": "outboundOS iPhone",
"all_workspaces": false
},
"owner": {
"id": "usr_zaDRRpdu8EPZSU3i89lvZgKPkVQo4uBFA_KOhm",
"email": "leon@leadarc.io",
"role": "admin"
},
"scopes": ["leads:read", "leads:write", "tasks:read", "tasks:write"],
"scopes_withheld": [],
"workspaces": [{
"object": "workspace",
"id": "airpay",
"name": "AirPay",
"member_id": "usr_zaDRRpdu8EPZSU3i89lvZgKPkVQo4uBFA_KOhm",
"slug": "airpay"
}]
}scopes is the usable set after intersecting the key's grant with the owner's current role. scopes_withheld names granted scopes the owner can no longer use.
workspaces is the live resolved set. On an all_workspaces key it grows as clients are onboarded. owner.id is a global one-part usr_… id for task, note, meeting, and other global member fields or filters. Each workspace's member_id is a two-part, workspace-scoped usr_… id for lead-assignment filters and writes. They identify the same person but are not interchangeable. slug is a deprecated alias for id and remains until v2.
Every enum value, limit, and filter this version accepts
curl -sS https://api.leadarc.io/v1/capabilities \
-H "Authorization: Bearer $LEADARC_API_KEY"No scope. responses_index.last_action, .category, and .meeting_outcome are all text with a TypeScript-only { enum: [...] } constraint. The only real Postgres enum types in the database are the ten orphaned finance_* types. A caller cannot learn the real vocabulary from anywhere except here.
Response (abridged):
{
"object": "capabilities",
"api_version": "v1",
"enums": {
"lead_status": ["interested", "not_interested", "automated", "unsubscribed", "untagged"],
"lead_state": ["active", "booked", "disqualified"],
"lead_classification": ["INTERESTED", "NOT_INTERESTED", "BAD_TIMING", "WRONG_PERSON", "AUTOMATED", "DNC"],
"meeting_outcome": ["showed", "no_show", "no_show_host", "cancelled", "rescheduled"],
"meeting_source": ["mark_booked", "calendar"],
"meeting_confirmation_status": ["confirmed", "pending", "declined"],
"meeting_location_type": ["google_meet", "phone", "zoom"],
"meeting_channel": ["Cold Email", "LinkedIn", "Cold Call", "Ads", "Referral", "Other"],
"message_direction": ["inbound", "outbound"],
"message_kind": ["reply", "campaign_send"],
"task_type": ["email", "call", "linkedin", "custom"],
"task_status": ["open", "completed"],
"asset_kind": ["loom", "doc", "link", "text"],
"asset_visibility": ["private", "workspace"],
"template_visibility": ["private", "workspace", "global"],
"sequence_visibility": ["private", "workspace", "global"],
"sequence_step_type": ["email", "call", "linkedin", "custom"],
"sequence_delay_unit": ["days", "hours"],
"enrollment_status": ["active", "paused", "completed", "cancelled"],
"event_type_scheduling_type": ["single", "collective", "round_robin"],
"event_type_form_field_type": ["text", "textarea", "select", "multiselect", "checkbox"],
"member_role": ["admin", "user"],
"assignment_source": ["auto", "manual"],
"assignment_method": ["off", "one", "all", "round_robin"]
},
"notes": {
"lead_classification": "The AI categorizer's verdict, passed through. BAD_TIMING and WRONG_PERSON are normalized to null on the tag path but can appear here verbatim. Tolerate values not in this list.",
"lead_status": "'dnc' is accepted as an input alias for 'unsubscribed' and is never returned. The app's own label for this state is 'Unsubscribed'.",
"asset_visibility": "There is no 'global' for assets, unlike templates and sequences. Sending it is 422."
},
"limits": {
"page_limit_max": 200,
"page_limit_default": 50,
"expand_max": 3,
"insights_window_days_max": 366,
"insights_daily_window_days_max": 120,
"slots_window_days_max": 60,
"messages_max_returned": 200
},
"filters": {
"leads": ["status", "campaign_id", "assignee_id", "lead_tag_id", "email", "q", "has_open_task",
"task_due_before", "meeting_outcome", "direction",
"updated_since", "updated_before", "unread", "responded", "priority"],
"tasks": ["lead_id", "assignee_id", "status", "due_before", "due_after", "task_type"],
"meetings": ["outcome", "source", "host_id", "event_type_id", "booked_since", "booked_before", "starts_after", "starts_before"],
"notes": ["lead_id", "author_id", "created_since"]
},
"expansions": {
"lead_list": ["assignees", "campaign", "open_tasks", "tags"],
"lead_detail": ["assignees", "open_tasks", "tags", "notes", "meetings"],
"max_per_request": 3
},
"ids": {
"me_owner": { "field": "owner.id", "prefix": "usr_", "parts": 1 },
"me_workspace_member": { "field": "workspaces[].member_id", "prefix": "usr_", "parts": 2 },
"lead_tag": { "field": "lead_BP2vnPmKyttNP2OlH_mWL78t1o6nBVC6oVbHny", "prefix": "ltg_", "parts": 2 }
},
"lead_tags": {
"roster": "GET /v1/workspaces/{ws}/lead_tags",
"assigned": "GET /v1/workspaces/{ws}/leads/{lead}/tags",
"replace": "PUT /v1/workspaces/{ws}/leads/{lead}/tags",
"filter_match": "any",
"filter_item_limit": 100,
"roster_order": "workspace",
"assigned_order": "applied",
"replace_semantics": "whole_set",
"replace_item_limit": null
},
"lead_priorities": {
"update": "PUT /v1/workspaces/{ws}/leads/priority",
"scope": "leads:write",
"owner_scoped": true,
"max_leads_per_request": 100
},
"lead_statuses": {
"update": "POST /v1/workspaces/{ws}/leads/{lead}/status",
"values": ["interested", "not_interested", "automated", "unsubscribed", "untagged"],
"base_scope": "leads:write",
"unsubscribe_scope": "leads:suppress",
"idempotency_key_required": true,
"untagged_is_local": true,
"unsubscribe_stops_provider_sends": true
},
"mobile_sessions": {
"create": "POST /v1/mobile/session",
"revoke_current": "DELETE /v1/mobile/session",
"token_prefix": "oos_mobile_",
"expires_in_days": 30,
"device_name_purpose": "audit_label",
"cryptographic_device_binding": false,
"active_sessions_per_user": 1,
"credential_identity": "stable_per_user",
"idempotency_claims_survive_reauthentication": true,
"new_sign_in_revokes_prior_sessions": true,
"workspace_grant": "snapshot_at_sign_in_intersected_with_live_access",
"revocation": "immediate"
},
"phases": {
"available": ["v1"],
"coming": {
"v2": ["bookings:write", "events:read", "webhooks:read", "webhooks:write"],
"v3": ["assignments:write", "enrichment:read"]
}
},
"deprecated": []
}The notes block is part of the contract. Half of the mistakes an integration makes are documentation problems, and serving the caveat next to the enum is cheaper than hoping someone read a docs page.