Max / API Docs

API Reference

The Max API lets you programmatically access your businesses, leads, signals, and subscriptions. Use it to build custom integrations, sync leads to your CRM, or automate your sales workflow.

Base URL: https://api.yourmax.ai/api/v1

CLI & MCP Server

Don't want to call the API directly? We offer two ready-made tools that wrap every endpoint documented below.

For AI Agents

Install the Max skill for your AI agent (Cursor, Claude Code, OpenClaw, etc.):

npx skills add sortlist/max-cli

This installs a SKILL.md that gives your agent full knowledge of the CLI commands, patterns, and workflows.

Both packages are open source: CLI source · MCP source

Authentication

All API requests (except the signal catalog) require an API key sent as a Bearer token in the Authorization header. API keys are scoped to your team — use the businesses endpoints to access each business's data.

Create API keys from Settings → API Keys in your dashboard.

Request header
Authorization: Bearer YOUR_API_KEY

Errors

The API returns standard HTTP status codes and a JSON error body.

Status Meaning
401Missing or invalid API key
404Resource not found
422Validation error
429Rate limit exceeded
Error response
{
  "error": "Unauthorized. Please provide a valid API key or OAuth token."
}

Pagination

List endpoints return paginated results. Use page and per_page query parameters.

Pagination metadata
{
  "meta": {
    "current_page": 1,
    "total_pages": 12,
    "total_count": 287,
    "per_page": 25
  }
}

Rate limits

The API is limited to 60 requests per minute per API key. Exceeding the limit returns a 429 response.

Signals

The signal catalog is public — no authentication required. Signals are the types of buying signals Max can detect (e.g. LinkedIn engagers, job changers, funding rounds).

GET /api/v1/signals

Returns all active signal types.

Response
{
  "signals": [
    {
      "id": 1,
      "name": "LinkedIn Company Engagers",
      "slug": "linkedin-company-engagers",
      "description": "Track people who engage with a company's LinkedIn posts.",
      "active": true,
      "default_config": { "engagement_types": ["like", "comment"] },
      "created_at": "2026-01-15T10:00:00Z",
      "updated_at": "2026-01-15T10:00:00Z"
    }
  ]
}
GET /api/v1/signals/:slug

Returns a single signal by its slug.

Businesses

Each team can have multiple businesses. All leads, subscriptions, and webhooks are scoped to a business. Use the business ID in the URL path when accessing those resources.

GET /api/v1/businesses

Returns all businesses in your team.

Response
{
  "businesses": [
    {
      "id": 1,
      "name": "Acme Corp",
      "slug": "acme-corp",
      "website": "https://acme.com",
      "description": "B2B SaaS for project management",
      "icon": null,
      "created_at": "2026-01-15T10:00:00Z",
      "updated_at": "2026-01-15T10:00:00Z"
    }
  ]
}
GET /api/v1/businesses/:id

Returns a single business with its Ideal Customer Profile.

Response
{
  "business": {
    "id": 1,
    "name": "Acme Corp",
    "slug": "acme-corp",
    "website": "https://acme.com",
    "description": "B2B SaaS for project management",
    "icon": null,
    "created_at": "2026-01-15T10:00:00Z",
    "updated_at": "2026-01-15T10:00:00Z",
    "ideal_customer_profile": {
      "id": 1,
      "target_job_titles": ["CTO", "VP of Engineering"],
      "target_locations": ["North America", "Europe"],
      "target_industries": ["Software", "Information Technology"],
      "company_types": ["Public Company", "Privately Held"],
      "company_sizes": ["51-200", "201-500"],
      "mandatory_keywords": ["SaaS", "engineering"],
      "excluded_companies": []
    }
  }
}
POST /api/v1/businesses

Create a new business. Supports two modes:

Website mode: Pass only a website URL. The API will automatically analyze the site and generate the business name, description, and Ideal Customer Profile. This may take a few seconds.

Parameter Type Required Description
name string conditional Business name (required in manual mode, auto-generated in website mode)
website string no Website URL. If passed alone, triggers auto-analysis
description string no Short description of the business
ideal_customer_profile_attributes object no ICP config — see ICP attributes reference below
Website mode (auto-analysis)
curl -X POST https://api.yourmax.ai/api/v1/businesses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "website": "https://acme.com" }'
Manual mode
curl -X POST https://api.yourmax.ai/api/v1/businesses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "website": "https://acme.com",
    "description": "B2B SaaS for project management",
    "ideal_customer_profile_attributes": {
      "target_job_titles": ["CTO", "VP of Engineering"],
      "target_locations": ["North America"]
    }
  }'

ICP attributes reference

The ideal_customer_profile_attributes object accepts the following fields. Fields marked with constrained values only accept the listed options — any other value will return a 422 error.

Field Type Description
id integer Required when updating an existing ICP (returned in GET response)
target_job_titles string[] Free text — any job titles (e.g. "CTO", "VP of Sales")
mandatory_keywords string[] Free text — keywords to require in lead profiles
excluded_companies string[] Free text — company names to exclude from results
target_locations string[] Constrained — see allowed values below
target_industries string[] Constrained — see allowed values below. Send [] for any industry; sending every value is stored as [].
company_types string[] Constrained — see allowed values below
company_sizes string[] Constrained — see allowed values below

Allowed values for target_locations

North America South America Europe Asia Africa Oceania Middle East Afghanistan Albania Algeria Andorra Angola Antigua and Barbuda Argentina Armenia Australia Austria Azerbaijan Bahamas Bahrain Bangladesh Barbados Belarus Belgium Belize Benin Bhutan Bolivia Bosnia and Herzegovina Botswana Brazil Brunei Bulgaria Burkina Faso Burundi Cambodia Cameroon Canada Cape Verde Central African Republic Chad Chile China Colombia Comoros Congo (Democratic Republic) Congo (Republic) Costa Rica Croatia Cuba Cyprus Czechia Denmark Djibouti Dominica Dominican Republic Ecuador Egypt El Salvador Equatorial Guinea Eritrea Estonia Eswatini Ethiopia Fiji Finland France Gabon Gambia Georgia Germany Ghana Greece Grenada Guatemala Guinea Guinea-Bissau Guyana Haiti Honduras Hungary Iceland India Indonesia Iran Iraq Ireland Israel Italy Ivory Coast Jamaica Japan Jordan Kazakhstan Kenya Kiribati Kosovo Kuwait Kyrgyzstan Laos Latvia Lebanon Lesotho Liberia Libya Liechtenstein Lithuania Luxembourg Madagascar Malawi Malaysia Maldives Mali Malta Marshall Islands Mauritania Mauritius Mexico Micronesia Moldova Monaco Mongolia Montenegro Morocco Mozambique Myanmar Namibia Nauru Nepal Netherlands New Zealand Nicaragua Niger Nigeria North Korea North Macedonia Norway Oman Pakistan Palau Palestine Panama Papua New Guinea Paraguay Peru Philippines Poland Portugal Qatar Romania Russia Rwanda Saint Kitts and Nevis Saint Lucia Saint Vincent and the Grenadines Samoa San Marino Sao Tome and Principe Saudi Arabia Senegal Serbia Seychelles Sierra Leone Singapore Slovakia Slovenia Solomon Islands Somalia South Africa South Korea South Sudan Spain Sri Lanka Sudan Suriname Sweden Switzerland Syria Taiwan Tajikistan Tanzania Thailand Timor-Leste Togo Tonga Trinidad and Tobago Tunisia Turkey Turkmenistan Tuvalu Uganda Ukraine United Arab Emirates United Kingdom United States Uruguay Uzbekistan Vanuatu Vatican City Venezuela Vietnam Yemen Zambia Zimbabwe

Allowed values for target_industries

Accounting Advertising Aerospace & Defense Agriculture Automotive Banking & Financial Services Biotechnology Construction Consulting Consumer Goods E-Commerce & Retail Education Energy & Utilities Entertainment & Media Environmental Services Food & Beverage Government & Public Sector Healthcare & Pharmaceuticals Hospitality & Tourism Human Resources & Staffing Insurance Legal Services Logistics & Supply Chain Manufacturing Marketing Mining & Metals Non-Profit & NGO Real Estate Software Development & SaaS Telecommunications Transportation

Allowed values for company_types

Public Company Private Company Startup Non-Profit Educational Government Self-Employed Partnership Sole Proprietorship

Allowed values for company_sizes

1-10 11-50 51-200 201-500 500+
PATCH /api/v1/businesses/:id

Update a business and/or its Ideal Customer Profile.

Parameter Type Description
name string Business name
website string Website URL
description string Short description
ideal_customer_profile_attributes object ICP fields to update — see ICP attributes reference above

Note: When updating the ICP, include the ICP id in ideal_customer_profile_attributes to update the existing profile. You can get the ICP id from the GET /api/v1/businesses/:id response. Array fields are replaced entirely — pass the full array, not just additions.

Update ICP
curl -X PATCH https://api.yourmax.ai/api/v1/businesses/1 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ideal_customer_profile_attributes": {
      "id": 1,
      "target_job_titles": ["CTO", "VP of Engineering", "Head of Product"],
      "target_locations": ["North America", "Europe"]
    }
  }'

Integrations

Integrations are third-party connections configured on a business (e.g. Overloop, Instantly, GetSales.io, Slack, Webhooks). Use these endpoints to list integrations and fetch campaigns or GetSales.io destinations for use with subscriptions and lead delivery.

GET /api/v1/businesses/:business_id/integrations

Returns all integrations for the business. Credentials are never exposed.

Response
{
  "integrations": [
    {
      "id": 5,
      "type": "overloop_ai",
      "display_name": "Overloop",
      "created_at": "2026-03-01T10:00:00Z"
    },
    {
      "id": 6,
      "type": "webhook",
      "display_name": "Webhook",
      "created_at": "2026-03-05T14:30:00Z"
    }
  ]
}
GET /api/v1/businesses/:business_id/integrations/:id/campaigns

Returns campaigns for a campaign-based integration. For GetSales.io, every automation contains its compatible lists and contact-source IDs; the top-level lists remain available for list-only destinations. Results may be cached for up to 5 minutes. Returns 422 if the integration does not support campaigns.

Response
{
  "campaigns": [
    {
      "id": "123",
      "name": "Outbound Q1 2026",
      "status": "on",
      "lists": [
        { "id": "789", "name": "Qualified prospects", "source_id": 7 }
      ]
    }
  ],
  "lists": [
    { "id": "789", "name": "Qualified prospects" }
  ]
}
Example request
curl https://api.yourmax.ai/api/v1/businesses/1/integrations/5/campaigns \
  -H "Authorization: Bearer YOUR_API_KEY"

Subscriptions

A subscription is a signal you've configured and activated — for example, "Track engagers on Apple's LinkedIn page." In the dashboard, these appear as your active signals. All subscription endpoints are scoped to a business.

GET /api/v1/businesses/:business_id/subscriptions

Returns all subscriptions for the business.

Response
{
  "subscriptions": [
    {
      "id": 42,
      "name": "Apple Engagers",
      "signal": {
        "name": "LinkedIn Company Engagers",
        "slug": "linkedin-company-engagers"
      },
      "config": { "linkedin_url": "https://www.linkedin.com/company/apple/" },
      "active": true,
      "integrations": [
        {
          "integration_id": 5,
          "type": "overloop_ai",
          "display_name": "Overloop",
          "auto_deliver": true,
          "campaign_id": "123",
          "campaign_name": "Outbound Q1 2026"
        }
      ],
      "last_checked_at": "2026-03-16T09:30:00Z",
      "created_at": "2026-02-01T12:00:00Z",
      "updated_at": "2026-03-16T09:30:00Z"
    }
  ]
}
GET /api/v1/businesses/:business_id/subscriptions/:id

Returns a subscription with stats.

Response
{
  "subscription": {
    "id": 42,
    "name": "Apple Engagers",
    "signal": { "name": "LinkedIn Company Engagers", "slug": "linkedin-company-engagers" },
    "config": { "linkedin_url": "https://www.linkedin.com/company/apple/" },
    "active": true,
    "integrations": [
      {
        "integration_id": 5,
        "type": "overloop_ai",
        "display_name": "Overloop",
        "auto_deliver": true,
        "campaign_id": "123",
        "campaign_name": "Outbound Q1 2026"
      }
    ],
    "last_checked_at": "2026-03-16T09:30:00Z",
    "created_at": "2026-02-01T12:00:00Z",
    "updated_at": "2026-03-16T09:30:00Z",
    "stats": {
      "total_leads": 847,
      "leads_today": 12
    }
  }
}
POST /api/v1/businesses/:business_id/subscriptions

Create a new subscription.

Parameter Type Required Description
signal_slug string yes Slug from the signal catalog
name string yes A name for this subscription
config object no Signal-specific configuration
integrations array no Integrations to link — see integration linking below
Example request bash
curl -X POST https://api.yourmax.ai/api/v1/businesses/1/subscriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "signal_slug": "linkedin-company-engagers",
    "name": "Apple Engagers",
    "config": {
      "linkedin_url": "https://www.linkedin.com/company/apple/"
    },
    "integrations": [
      {
        "integration_id": 5,
        "auto_deliver": true,
        "campaign_id": "123",
        "campaign_name": "Outbound Q1 2026"
      }
    ]
  }'

Linking integrations to a subscription

Pass an integrations array when creating or updating a subscription. Each entry links an integration and configures auto-delivery. For campaign-based integrations, include the campaign ID and name. A GetSales.io destination encodes the selected list and, when applicable, the automation.

Field Type Required Description
integration_id integer yes ID from the integrations list
auto_deliver boolean no Automatically send new leads to this integration (default: false)
campaign_id string conditional Required for campaign-based integrations when auto_deliver is true. Get IDs from the campaigns endpoint. For GetSales.io use list:<list_uuid> or the destination exposed for a compatible automation source: flow:<flow_uuid>:source:<source_id>:list:<list_uuid>. (Legacy alias: overloop_campaign_id)
campaign_name string no Campaign name for display purposes (Legacy alias: overloop_campaign_name)

Note: The integrations array replaces all linked integrations. Omit the field entirely to leave integrations unchanged. Pass an empty array to remove all links.

PATCH /api/v1/businesses/:business_id/subscriptions/:id

Update a subscription's name, config, active state, or linked integrations.

Link a campaign integration
curl -X PATCH https://api.yourmax.ai/api/v1/businesses/1/subscriptions/42 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integrations": [
      {
        "integration_id": 5,
        "auto_deliver": true,
        "campaign_id": "123",
        "campaign_name": "Outbound Q1 2026"
      }
    ]
  }'
POST /api/v1/businesses/:business_id/subscriptions/:id/pause

Pause a subscription. The signal will stop scanning for new leads until resumed. Returns the updated subscription object.

Example
curl -X POST https://api.yourmax.ai/api/v1/businesses/1/subscriptions/42/pause \
  -H "Authorization: Bearer YOUR_API_KEY"

# Returns the subscription with "active": false
POST /api/v1/businesses/:business_id/subscriptions/:id/resume

Resume a paused subscription. The signal will start scanning for new leads again. Returns the updated subscription object.

Example
curl -X POST https://api.yourmax.ai/api/v1/businesses/1/subscriptions/42/resume \
  -H "Authorization: Bearer YOUR_API_KEY"

# Returns the subscription with "active": true
DELETE /api/v1/businesses/:business_id/subscriptions/:id

Delete a subscription. Returns 204 No Content.

Leads

Leads are the enriched profiles discovered by your active signals. Each lead includes name, email, job title, company, LinkedIn URL, and more. All lead endpoints are scoped to a business.

GET /api/v1/businesses/:business_id/leads

Returns leads for the business, newest first. Paginated.

Parameter Default Description
page 1 Page number
per_page 25 Results per page (max 100)
Response
{
  "leads": [
    {
      "id": 1234,
      "external_id": "li_abc123",
      "name": "John Doe",
      "headline": "Senior Sales Manager at Example Corp",
      "job_title": "Senior Sales Manager",
      "email": "[email protected]",
      "phone": "+1234567890",
      "linkedin_url": "https://www.linkedin.com/in/johndoe",
      "profile_picture": "https://media.licdn.com/...",
      "location": "San Francisco, CA",
      "company": "Example Corp",
      "company_logo": "https://media.licdn.com/...",
      "company_industry": "Software",
      "company_size": "51-200",
      "company_website": "https://example.com",
      "company_linkedin": "https://www.linkedin.com/company/example-corp/",
      "company_founded": "2015",
      "connections": 500,
      "followers": 1200,
      "icp_score": 85,
      "engagement_type": "like",
      "post_url": "https://www.linkedin.com/feed/update/urn:li:activity:123",
      "signals": [
        { "name": "LinkedIn Company Engagers", "slug": "linkedin-company-engagers" }
      ],
      "subscription_ids": [42],
      "payload": { "..." : "..." },
      "triggered_at": "2026-03-16T09:15:00Z",
      "created_at": "2026-03-16T09:15:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total_pages": 12,
    "total_count": 287,
    "per_page": 25
  }
}
GET /api/v1/businesses/:business_id/leads/:id

Returns a single lead with delivery history.

Response (partial)
{
  "lead": {
    "id": 1234,
    "external_id": "li_abc123",
    "name": "John Doe",
    "headline": "Senior Sales Manager at Example Corp",
    "job_title": "Senior Sales Manager",
    "email": "[email protected]",
    "phone": "+1234567890",
    "linkedin_url": "https://www.linkedin.com/in/johndoe",
    "profile_picture": "https://media.licdn.com/...",
    "location": "San Francisco, CA",
    "company": "Example Corp",
    "company_logo": "https://media.licdn.com/...",
    "company_industry": "Software",
    "company_size": "51-200",
    "company_website": "https://example.com",
    "company_linkedin": "https://www.linkedin.com/company/example-corp/",
    "company_founded": "2015",
    "connections": 500,
    "followers": 1200,
    "icp_score": 85,
    "engagement_type": "like",
    "post_url": "https://www.linkedin.com/feed/update/urn:li:activity:123",
    "signals": [...],
    "subscription_ids": [42],
    "payload": { "..." : "..." },
    "triggered_at": "2026-03-16T09:15:00Z",
    "created_at": "2026-03-16T09:15:00Z",
    "deliveries": [
      {
        "id": 567,
        "integration_type": "Webhook",
        "status": "delivered",
        "delivered_at": "2026-03-16T09:15:02Z"
      }
    ]
  }
}
POST /api/v1/businesses/:business_id/leads/enroll

Send one or more leads to a campaign-based integration (Overloop, Instantly, or GetSales.io). GetSales.io accepts either a list destination or an automation plus its required storage list. Leads without an email or LinkedIn URL are skipped. Enrollment is asynchronous — leads are queued for delivery.

Parameter Type Required Description
integration_id integer yes Campaign integration ID (Overloop, Instantly, or GetSales.io) from the integrations list
campaign_id string yes Campaign ID from the campaigns endpoint. For GetSales.io, use list:<list_uuid> or the destination exposed for a compatible automation source: flow:<flow_uuid>:source:<source_id>:list:<list_uuid>.
lead_ids integer[] yes Array of lead IDs to enroll
Example request
curl -X POST https://api.yourmax.ai/api/v1/businesses/1/leads/enroll \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_id": 5,
    "campaign_id": "123",
    "lead_ids": [10, 11, 12]
  }'
Response
{
  "enqueued": 2,
  "skipped": 1
}
DELETE /api/v1/businesses/:business_id/leads/:id

Soft-deletes a lead. The lead will no longer appear in list results but can be recovered by the Max team if needed. Returns 204 No Content on success.

Example
curl -X DELETE https://api.yourmax.ai/api/v1/businesses/1/leads/1234 \
  -H "Authorization: Bearer YOUR_API_KEY"

# 204 No Content

Webhooks

Register a URL to receive an HTTP POST in real-time whenever a new lead is discovered. Webhooks are scoped to a business.

GET /api/v1/businesses/:business_id/webhooks

List all registered webhooks for the business.

POST /api/v1/businesses/:business_id/webhooks

Register a new webhook.

Parameter Type Required Description
url string yes The URL to receive POST requests
secret string no Secret to sign payloads (recommended)
Example request
curl -X POST https://api.yourmax.ai/api/v1/businesses/1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/signals",
    "secret": "whsec_your_secret_here"
  }'
DELETE /api/v1/businesses/:business_id/webhooks/:id

Delete a webhook. Returns 204 No Content.

Webhook payload

When a new lead is discovered, we send a POST to your URL with this payload:

POST to your webhook URL
{
  "event": "lead.discovered",
  "lead": {
    "id": 1234,
    "external_id": "li_abc123",
    "name": "John Doe",
    "headline": "Senior Sales Manager at Example Corp",
    "linkedin_url": "https://www.linkedin.com/in/johndoe",
    "company": "Example Corp",
    "discovered_at": "2026-03-16T09:15:00Z",
    "payload": { "email": "[email protected]", "..." : "..." }
  },
  "monitor": {
    "id": 42,
    "name": "Apple Engagers",
    "signal": "LinkedIn Company Engagers"
  },
  "team": {
    "id": 1,
    "name": "My Team"
  }
}

Verifying signatures

If you provided a secret, each request includes an X-Signals-Signature header. Compute HMAC-SHA256 of the raw body with your secret and compare:

Python
import hmac, hashlib

expected = "sha256=" + hmac.new(
    secret.encode(), raw_body, hashlib.sha256
).hexdigest()

assert hmac.compare_digest(
    expected, request.headers["X-Signals-Signature"]
)
JavaScript / Node.js
const crypto = require("crypto");

const expected = "sha256=" + crypto
  .createHmac("sha256", secret)
  .update(rawBody)
  .digest("hex");

if (expected !== req.headers["x-signals-signature"]) {
  throw new Error("Invalid signature");
}

Zapier

Max integrates with Zapier to connect your leads to 5,000+ apps. The integration uses OAuth 2.0 — connect with one click from the Zapier dashboard.

Open Max on Zapier

Max CLI

Use the Max CLI to manage signals, subscriptions, leads, and webhooks directly from the terminal. The CLI outputs JSON, making it easy to pipe into jq or use with AI agents like Claude Code and OpenClaw.

Install & setup
npm install -g sortlist-max-cli
export MAX_API_KEY=your_api_key

max businesses:list
max leads:list --business 1
max subscriptions:pause 42 --business 1
max webhooks:create --url https://example.com/webhook --business 1

View on GitHub