Build on the NetworkHQ API.
Explore the public API, authorize with a workspace key, and test AI campaign creation and lifecycle actions, sender warm-up, leads, enrichment, and conversations in a dedicated OpenAPI reference.
Sample request
List conversations
Authorization: Bearer nhq_live_...
{
"data": [{
"lead": {
"first_name": "Priya",
"last_name": "Shah"
},
"intent": "INTERESTED",
"last_message": {
"direction": "received",
"content": "Interested - send details."
}
}]
}conversations:read
Direction included
Spec
OpenAPI 3.1
Ready for docs, client generators, and external tooling.
Auth
Bearer API key
Authorize once in the reference with a workspace-scoped token.
Base URL
https://api.networkhq.io/api/v1
Requests are scoped to the workspace that owns the API key.
Two lines to your
first response.
Pick your language, copy the snippet, and replace the key. Conversation responses include the real latest message content and direction.
curl -G "https://api.networkhq.io/api/v1/conversations?limit=10" \ -H "Authorization: Bearer nhq_live_..."
Sample response
{ "data": [ { "id": "conv_01jwxq...", "intent": "INTERESTED", "is_unread": true, "last_message": { "direction": "received", "content": "Interested - send details." } } ], "pagination": {"has_more": false} }
Hand your agent the whole API in one paste.
We publish a plain-text brief built for models. It teaches an LLM the base URL, how to authenticate, where to get an API key, and points it at the live OpenAPI schema so it can call endpoints on its own.
01Paste the prompt
Drop llms.txt into your agent's system prompt or context window. It explains the base URL, auth, and pagination in one block.
02Add a scoped key
Generate a workspace API key in Settings, grant only the scopes you need, and hand it to the agent as a secret.
03Let it read the schema
The agent fetches openapi.json and builds correct, typed requests itself — no hand-written client required.
# NetworkHQ Public API — Guide for AI agents & LLMs
You are an assistant integrating with the NetworkHQ public API on behalf of a
single workspace. Read this guide, then drive every request from the live
OpenAPI schema below.
## 1. Base URL
https://api.networkhq.io/api/v1
## 2. Schema is the source of truth
Fetch the OpenAPI 3.1 contract before building any request:
GET https://api.networkhq.io/api/v1/openapi.json
It lists every path, query parameter, request body, and response shape. Always
trust the schema over assumptions — paths and fields may change.
## 3. Authentication
Every request needs a workspace-scoped API key sent as a bearer token:
Authorization: Bearer nhq_live_...
Create a key as a workspace OWNER or MANAGER:
https://app.networkhq.io -> Settings -> API Keys -> Create key
Grant only the scopes your integration needs (read/write per resource). A key is
shown once at creation — store it as a secret and never print it back.
## 4. Conventions
- Send and expect JSON.
- List endpoints are cursor-paginated: pass ?limit= and ?cursor=, then follow
pagination.next_cursor while pagination.has_more is true.
- Status codes: 400 invalid request, 401 missing/invalid key,
403 key lacks the required scope, 404 not found, 429 rate limited.
## 5. Endpoints and required scopes
GET /agents/product agents:read
POST /agents/product-previews agents:write
POST /agents/generations agents:write
GET /agents/generations/{generation_id} agents:read
GET /agents agents:read
POST /agents agents:write
GET /agents/{agent_id} agents:read
PATCH /agents/{agent_id} agents:write
POST /agents/{agent_id}/actions agents:write
GET /campaigns campaigns:read
POST /campaigns campaigns:write
GET /campaigns/{campaign_id} campaigns:read
PATCH /campaigns/{campaign_id} campaigns:write
POST /campaigns/{campaign_id}/actions campaigns:write
GET /campaigns/{campaign_id}/leads campaigns:read
PUT /campaigns/{campaign_id}/leads/{lead_id}/message-overrides campaigns:write
GET /campaigns/{campaign_id}/message-approvals campaigns:read
POST /campaigns/{campaign_id}/message-approvals/{message_id}/actions campaigns:write
GET /linkedin_accounts linkedin_accounts:read
PATCH /linkedin_accounts/{linkedin_account_id} linkedin_accounts:write
GET /lead_lists lead_lists:read
POST /lead_lists lead_lists:write
GET /lead_lists/{lead_list_id} lead_lists:read
GET /lead_lists/{lead_list_id}/leads leads:read
POST /lead_lists/{lead_list_id}/leads leads:write
GET /leads leads:read
GET /leads/{lead_id} leads:read
POST /leads/{lead_id}/enrich leads:write
GET /conversations conversations:read
GET /conversations/{conversation_id} conversations:read
GET /conversations/{conversation_id}/messages/{message_id}/attachments/{attachment_index} conversations:read
POST /conversations/{conversation_id}/messages conversations:write
## 6. Example request
curl -G "https://api.networkhq.io/api/v1/conversations?limit=10" \
-H "Authorization: Bearer nhq_live_..."
## 7. Rules for the agent
1. Load https://api.networkhq.io/api/v1/openapi.json first and build requests from it.
2. Use only the scopes the key was granted; if a 403 means a missing scope, tell
the user which scope to add rather than retrying.
3. Page through list endpoints with the cursor until has_more is false.
4. Treat the API key as a secret — never echo it back to the user.
5. Confirm with the user before any write action (sending a message, importing
leads, or enriching) that changes workspace data or spends credits.
Workspace data, ready for external systems.
Public endpoints for complete Create-with-AI campaign drafts, campaign reporting and launch controls, sender warm-up, lead management, enrichment, and conversations.
Get the saved workspace product
Returns the canonical complete product currently saved in the API key workspace. Pass this product unchanged to the generation endpoint with `replace_existing_product` set to false to prepare an agent without replacing the workspace product. Requires `agents:read`.
Extract an editable product preview
Extracts product details without persisting them. Review and edit the result before starting a generation. Requires `agents:write`.
Confirm product details and prepare agent suggestions
Persists the reviewed product atomically and starts or reuses ICP, competitor, and keyword preparation. Set `replace_existing_product` to true when intentionally replacing a different saved product. Requires `agents:write`.
Poll agent suggestion preparation
Returns `preparing`, `ready`, or `manual_input_required`. A manual-input result can still be used to create an agent when complete reviewed criteria and signals are supplied. Requires `agents:read`.
List lead generation agents
Cursor-paginated agents in the API key workspace, optionally filtered by lifecycle status. Requires `agents:read`.
Create a draft lead generation agent
Creates a draft from a current ready or manual-input generation and the caller's reviewed targeting. The destination must be a normal lead list in the API key workspace. Requires `agents:write`.
Get an agent's editable configuration
Returns complete criteria and signals for an agent in the API key workspace. Requires `agents:read`.
Update an agent without changing its status
Updates scalar fields. Supplied `criteria` or `signals` replace that entire section; `add_signals` appends to the existing signal configuration without requiring callers to resubmit it. `signals` and `add_signals` cannot be combined. Omitted sections remain unchanged. Active agents are rescheduled atomically and cannot be left without a runnable signal. Requires `agents:write`.
Activate, pause, or resume an agent
Valid transitions are draft → active (`activate`), active → paused (`pause`), and paused → active (`resume`). Requires `agents:write`.
List campaigns for the API key workspace
Returns every outreach campaign in the API key workspace, newest first. Each campaign includes its lifecycle `status` (`draft`, `started`, `paused`, `completed`), aggregate performance metrics (total leads, connection requests sent and accepted, messages sent, replies received), the LinkedIn sender accounts assigned to it, and the source lead list when one is configured. Results are cursor-paginated (`limit` 1–500, default 100). Requires the `campaigns:read` scope.
Create a complete Create-with-AI campaign draft
Creates a draft using the app-compatible Create with AI workflow. Launch it separately with the campaign action endpoint. Requires `campaigns:write`; inline lead imports also require `leads:write`.
Get a campaign
Returns lifecycle metrics plus the complete persisted Create-with-AI setup, including objective, schedule, approval preference, message sequence, engagement, and connection request. Requires `campaigns:read`.
Edit Create-with-AI campaign setup
Updates one or more campaign setup sections using the same persisted campaign, schedule, workflow, cache-invalidation, and approval rules as the app. Schedule and workflow fields require a draft or paused campaign; pause an active campaign first. Requires `campaigns:write`.
Run a campaign lifecycle action
Starts, pauses, or resumes one campaign in the API key workspace using the same lifecycle boundaries as the campaign settings UI. `start` is only valid for draft campaigns and requires a configured lead list, schedule, connected LinkedIn sender account, and message setup; it enrolls every lead from the source lead list. LinkedIn session health is checked first. A failed or unavailable check returns `linkedin_session_check_failed`, keeps the campaign in draft, and includes per-account health plus an explicit Proceed Anyway request. Send that request only when the caller chooses to accept the risk. `pause` is only valid for active campaigns. `resume` is only valid for paused campaigns and reactivates both the campaign and its paused leads. Requires the `campaigns:write` scope.
List campaign leads with status-table fields
Lists the leads enrolled in a campaign with the same fields shown in the campaign status table, newest enrollment first. Each row includes the lead's current funnel state (connection, InMail, and message status with the last-action timestamp), enrollment `status` and `priority`, reply `intent` and its source, the assigned LinkedIn sender, and a chronological `actions_performed` timeline of every action taken or scheduled for that lead. Cursor-paginated (`limit` 1–500, default 100). Returns 404 when the campaign does not exist in the API key workspace. Requires the `campaigns:read` scope.
Save lead-level campaign message overrides
Sets the exact text to send to one lead for an AI-personalized or template-backed campaign message slot. The lead-level override takes precedence over the campaign slot's AI generation or template text. `send_message` supports all three stages with an 8000-character limit. `send_connection` supports only the `ice_breaker` stage with a 200-character limit. The shared override service preserves the app's locking, approval, and protected-token rules. Requires `campaigns:write`.
List persisted AI message approvals for a campaign
Lists persisted pending, approved, and rejected message rows for one campaign. Cursor-paginated newest first. Requires `campaigns:read`.
Approve or reject a campaign AI message
Resolves one pending approval using the same campaign lock, audit fields, lead release, and rejection exclusion behavior as the app. Requires `campaigns:write`.
List LinkedIn accounts for the API key workspace
Lists the LinkedIn sender accounts connected to the API key workspace, newest first. Each account includes its connection `status` (`connecting`, `connected`, `disconnected`, `error`, `awaiting_code`), `account_tier` (`regular`, `premium`, `sales_navigator`), the configured daily sending limits and warm-up flag, current connection and pending-invite counts, and the last-run and cooldown timestamps. Cursor-paginated (`limit` 1–500, default 100). Requires the `linkedin_accounts:read` scope.
Configure LinkedIn account sending limits
Turns warm-up on or off and configures daily sending limits for an existing LinkedIn account in the API key workspace. Disabling warm-up without supplying limits sets every daily limit to 10; re-enabling it restores the warm-up-controlled defaults. Manual limits can be changed only while warm-up is off or when the same request turns it off. Requires the `linkedin_accounts:write` scope.
List lead lists for the API key workspace
Lists every lead list in the API key workspace, newest first, each with its current member count. Cursor-paginated (`limit` 1–500, default 100). Requires the `lead_lists:read` scope.
Create one or more lead lists for the API key workspace
Creates one or more lead lists in the API key workspace from either a single lead-list object or the `lead_lists` batch array. List names are made unique automatically — a name that collides with an existing list is suffixed (for example `Founders (Copy ...)`). The response returns the created lists in `data`, any rejected entries in `malformed`, and a `summary` of attempted/created/malformed counts. Returns 201 when every list was created and 207 when some entries were malformed but others succeeded. Requires the `lead_lists:write` scope.
Get a lead list from the API key workspace
Returns a single lead list in the API key workspace, including its current member count. Returns 404 when the list does not exist in the workspace. Requires the `lead_lists:read` scope.
List leads in a lead list from the API key workspace
Lists the leads that are members of a specific lead list, newest membership first, each with enriched company details plus lead heat score and reason when available. Cursor-paginated (`limit` 1–500, default 100). Returns 404 when the list does not exist in the API key workspace. Requires the `leads:read` scope.
Create one or more leads in a lead list
Imports leads into a lead list. Accepts either a single lead object or a batch via the `leads` array (up to 100 per request). Leads are de-duplicated against the workspace, and each result is reported as `created` (a new lead was created and added), `added_existing` (an existing workspace lead was added to this list), or `already_in_list` (the lead was already a member).
List all leads for the API key workspace
Lists every lead in the API key workspace, newest first, each with enriched company details, the IDs of the lead lists it belongs to, plus lead heat score and reason when available. Pass `query` to full-text search across first name, last name, company, job title, location, and email (space-separated terms are AND-matched, case-insensitive). Pass `list_ids` (comma-separated lead list IDs) to return only leads that belong to those lists. Cursor-paginated (`limit` 1–500, default 100). Requires the `leads:read` scope.
Get a lead from the API key workspace
Returns a single lead in the API key workspace, including enriched company details, the IDs of the lead lists it belongs to, plus lead heat score and reason when available. Returns 404 when the lead does not exist in the workspace. Requires the `leads:read` scope.
Enrich Lead Profile
Enriches a lead's profile and company details from the enrichment provider. The `enrichment.status` reports the outcome: `enriched` (newly enriched), `already_enriched` (returned existing data without re-charging), `insufficient_credits` (not enough credits to enrich), or `failed` (the provider could not enrich the lead). `charged` indicates whether a credit was consumed, and `credits_remaining` reports the workspace balance after the call. Returns 404 when the lead does not exist in the workspace, 502 when the enrichment provider errors, and 503 when the automation service is unavailable. Requires the `leads:write` scope.
List conversations for the API key workspace
Lists LinkedIn conversations across the API key workspace, ordered by most recent message. Each conversation includes the associated lead, the LinkedIn sender account, the reply `intent` when one has been classified, an unread flag, and a preview of the latest message. Filter with `unread_only=true` to return only unread threads and `linkedin_account_id` to scope results to a single sender account. Cursor-paginated (`limit` 1–500, default 100). Requires the `conversations:read` scope.
Get a conversation and its messages
Returns a single conversation with its message history in chronological order (oldest first), plus the associated lead, LinkedIn sender account, and reply `intent`. Messages are cursor-paginated (`limit` 1–500, default 100). Returns 404 when the conversation does not exist in the API key workspace, 502 when delegated history contains an invalid cursor, and 503 when conversation history is temporarily unavailable. Requires the `conversations:read` scope.
Stream a conversation message attachment
Streams supported LinkedIn image, external-media, audio, or video content through the authenticated API without exposing provider credentials. Range requests are forwarded for audio and video playback. Returns 416 when the Range header is invalid. Requires the `conversations:read` scope.
Send a message to a conversation
Sends a plain-text message into an existing LinkedIn conversation through the workspace's automation sender (maximum 8000 characters). On success the response reports `ok: true`; `pending: true` means LinkedIn accepted the send but did not immediately return a message id, in which case the message will appear after the next inbox sync. Returns 404 when the conversation does not exist in the workspace, 409 when the conversation is still syncing, 502 when the send fails, and 503 when message sending is temporarily unavailable. Requires the `conversations:write` scope.
From API key to first request without guesswork.
Keep setup inside NetworkHQ, then use the generated key in this reference or any external integration that can send bearer-token requests.
- 1
Create the key
Generate a workspace API key from NetworkHQ settings.
- 2
Choose scopes
Grant only the public API permissions your integration needs.
- 3
Authorize the docs
Paste the token into Swagger's Authorize dialog and keep it for the session.
- 4
Ship against the schema
Test requests here or open the raw OpenAPI JSON in a new tab.
Test the public API on its own page.
Open the dedicated Swagger UI page to authorize with a bearer token and run live requests against the public API schema. The raw configuration is still available at https://api.networkhq.io/api/v1/openapi.json.