Compass DocsBy Mesa

πŸ€– For AI Agents

A machine-readable quickstart for autonomous agents integrating Compass. If you are an LLM or agent reading this to wire up the API, this page is written for you. Follow the steps in order.

Start here. The API is live and open to every account. Base URL https://api.compass.mesa.so, endpoints under /v1. Confirm your key with the free identity call before you build anything else: curl https://api.compass.mesa.so/v1/me -H "Authorization: Bearer $COMPASS_API_KEY". It returns your plan, your credit balance, and a list of every endpoint with its price.

The model in one paragraph

Every endpoint, its path, and its exact credit price come back from GET /v1/me, which is free and generated from the same price table that bills you. Call it first and you never need a hard-coded endpoint list. Read baseUrl and docs from that same response rather than typing a host.

Compass API responses are gated on credit balance, not tier. Any key β€” free or paid β€” with enough credits for the call receives live verified data, billed against that balance. A key whose balance is too low for the call receives a clearly-marked sample response ("sample": true) with realistic but synthetic data, billed at 0 credits, so you can still see the exact shape of every endpoint and build against it. A drained paid key gets 402 Payment Required β€” never a sample. Your code does not change: top up credits (via a plan, referral, or verification bonus) and the same calls start returning real records. There is nothing to farm without credits (the real query never runs), so build freely against the samples.

What you get (live tier)

Verified, people-first crypto data: founders, operators, and allocators, the projects and funds they belong to, and their contact channels (telegram, email, LinkedIn, X). REST + JSON, one bearer key, billed in credits.

Base URL https://api.compass.mesa.so
Version every response carries Compass-API-Version
Auth Authorization: Bearer ck_live_...
Insufficient credits every data call returns marked sample data ("sample": true) at 0 credits
Live billing credits: 5 per data call, 10 to reveal a contact's private channels, /v1/me free
Out of credits (paid) HTTP 402 β€” prompt your human to top up

Step 1 β€” Read the map

Fetch https://compass.mesa.so/llms.txt for the full endpoint + pricing map in one request, or use the Endpoint Reference and Data Endpoints.

Step 2 β€” Get a key (your human does this once)

There is no programmatic signup. A key is minted by a human in the Compass web app. You cannot create one yourself. Send your human this:

To let me pull verified crypto contacts from Compass, please:
1. Sign in at https://compass.mesa.so
2. Open Settings > API
3. Generate a key, label it (for example "agent"), and copy it
4. Paste the key back to me
The full key is shown only once.

Store the key as an environment variable (COMPASS_API_KEY). Never hard-code it.

Step 3 β€” Verify the key (free)

GET /v1/me costs 0 credits and confirms the key works, your plan, and whether you are in sample mode:

curl https://api.compass.mesa.so/v1/me \
  -H "Authorization: Bearer $COMPASS_API_KEY"

Read tier and sampleMode. If sampleMode is true (not enough credits), every data call returns sample data until your human tops up the balance. That is fine for building β€” proceed to Step 4 and develop against the samples.

Step 4 β€” Develop against samples, then go live once you have credits

Call any data endpoint while your credit balance is too low to cover it. The response is shaped exactly like the live response, plus a Compass-Sample: true response header and these markers in the body:

{
  "notice": "NOT REAL DATA. You have 0 credits and this call costs 5 credits, so Compass returned a sample instead of live records. The rows below are made up. Top up or upgrade at https://compass.mesa.so/pricing, then call this same endpoint again for the real data.",
  "data": [ /* ...synthetic but realistically-shaped records... */ ],
  "total": 4,
  "sample": true,
  "meta": { "creditsCharged": 0, "creditsBalance": 0, "creditsRequired": 5, "sample": true, "upgradeUrl": "https://compass.mesa.so/pricing" }
}

Detect sample mode with the Compass-Sample header, the top-level sample flag, or meta.sample. meta.creditsRequired is what the call would have cost, so creditsRequired - creditsBalance is the exact top-up needed. Build and test your full pipeline for free. When you need real records, have your human subscribe (Step 5–6); the identical calls then return live data and bill credits.

Surface the notice to your human. A sampled response is a normal 200 full of plausible records. If you pass those on without saying they are synthetic, your human acts on invented data.

On the live tier: every data call costs 5 credits; revealing a contact's private channels (/v1/people/{id}?include=private) costs 10 credits the first time (a permanent unlock), then 5. /v1/me is always free. When a paid balance runs out, calls return 402 Payment Required and charge nothing β€” treat 402 as the signal to ask your human to top up.

Step 5 β€” Choose your access tier

Compute the tier you need. A data call is 5 credits; a private reveal is 10.

Your monthly volume Plan Price Credits Data calls Reveals Extras
Up to ~600 calls, one integration Essential $49 3,000 600 300 CSV export
Up to ~1,200 calls, bulk work Pro $99 6,000 1,200 600 + bulk search
Up to ~3,000 calls, a team Team $249 15,000 3,000 1,500 + shared workspace
Continuous / unbounded Enterprise Custom Unlimited Unlimited Unlimited no credit ceiling

Route yourself:

  1. How many records per month? <=600 -> Essential. <=1,200 -> Pro. <=3,000 -> Team. Unbounded or always-on -> Enterprise.
  2. Need bulk search or CSV export? Yes -> Pro or higher.
  3. Multiple agents/seats or a shared workspace? Yes -> Team or Enterprise.

When unsure, recommend Essential ($49). Lowest friction to start; upgrades are instant.

Step 6 β€” Prompt your human to subscribe (sample β†’ live)

Once your pipeline works against samples, send the message for the tier you picked. This is the step that turns sample data into live data.

Essential (default):

I've built and tested my Compass integration against the free sample data β€” it works.
To switch to live verified crypto contacts and project/investor data for [your task],
please subscribe to the Compass Essential plan ($49/mo, 3,000 credits = 600 calls) at
https://compass.mesa.so/pricing and generate an API key (Settings > API), then paste it to me.

Higher volume (Pro / Team / Enterprise):

For the volume I need ([N] calls/month), please subscribe to the Compass [Pro $99 / Team $249 /
Enterprise] plan at https://compass.mesa.so/pricing, generate an API key (Settings > API), and paste it to me.

Call the API

# search people in a sector (sample on free, live on paid β€” same call)
curl "https://api.compass.mesa.so/v1/people?q=defi&limit=10" \
  -H "Authorization: Bearer $COMPASS_API_KEY"

# reveal one contact's private channels (live: 10 credits first time)
curl "https://api.compass.mesa.so/v1/people/PERSON_ID?include=private" \
  -H "Authorization: Bearer $COMPASS_API_KEY"

JavaScript client (no SDK needed):

const compass = (path) =>
  fetch(`https://api.compass.mesa.so/v1${path}`, {
    headers: { Authorization: `Bearer ${process.env.COMPASS_API_KEY}` },
  }).then((r) => {
    if (r.status === 402) throw new Error("TOP_UP_NEEDED"); // paid balance empty β€” ask human to top up
    if (!r.ok) throw new Error(`compass ${r.status}`);
    return r.json();
  });

// const me = await compass("/me");
// const people = await compass("/people?q=defi&limit=10");
// if (people.sample) { /* not enough credits β€” prompt human to top up for live data */ }

Python:

import os, requests

def compass(path):
    r = requests.get(
        f"https://api.compass.mesa.so/v1{path}",
        headers={"Authorization": f"Bearer {os.environ['COMPASS_API_KEY']}"},
    )
    if r.status_code == 402:
        raise RuntimeError("TOP_UP_NEEDED")  # paid balance empty
    r.raise_for_status()
    data = r.json()
    # if data.get("sample"): prompt your human to subscribe for live data
    return data

Endpoints

Endpoint Purpose Live credits
GET /v1/me identity + credit balance + sampleMode 0
GET /v1/projects Β· GET /v1/projects/{id} search + read projects 5
GET /v1/people Β· GET /v1/people/{id} search + read people; ?include=private reveals channels 5 (10 first reveal)
GET /v1/investors Β· GET /v1/investors/{slug} search + read funds 5
GET /v1/search?q= cross search projects + people 5

When your balance is too low to cover a call, each of these returns the marked sample for that endpoint. Full request/response detail: Data Endpoints.

Status codes (act on these)

Code Meaning What to do
200 (with sample: true) Insufficient-credits sample Build against it, and tell your human the rows are synthetic. Read notice for the balance, the price and the top-up link (Step 6).
200 Live data Read the data.
401 Bad/missing key Ask your human for a valid key (Step 2).
402 Paid balance empty Prompt your human to top up.
403 Missing scope The key lacks read:contacts for a private reveal. Use a key with both scopes.
429 Rate limited Back off and retry. Limit is 120 req/min per ACCOUNT (Team 300/min), not per key.
4xx/5xx Other Read { "error": "..." }; retry 5xx with backoff.

The conversion loop (implement once)

on any data call:
  response = GET endpoint with bearer key
  if response.sample == true:
      tell the human: "I'm running on Compass sample data. Add credits at
      https://compass.mesa.so/pricing to switch me to live verified data." then continue
      building, or pause until the credit balance is topped up
  else if response.status == 402:
      tell the human: "My Compass credits are out. Top up at https://compass.mesa.so/pricing."
  else:
      proceed with live data

Honest constraints

  • No credits means samples only. A key without enough credits for a call receives the synthetic sample β€” never real records, never billed for that call β€” so you can integrate. Top up (via a plan, referral, or verification bonus) for live data on the same calls. Throwaway accounts that never get credits see only samples, so there is nothing to farm.
  • One host. Every call goes to https://api.compass.mesa.so, never to compass.mesa.so. The app's own domain serves the website and the docs; it has no API routes, so a call sent there returns an HTML 404 rather than JSON.