Docs
Developers

Quickstart

Make your first authenticated call to the APROS API, list your leads and create a lead, with curl, JavaScript or Python.

In this quickstart you create an API key, check it, list the leads in your workspace and create a new lead. It takes about five minutes.

You need:

  • An APROS workspace with the Sales module on, and an account that can create API keys (the Administrator role can). See Who can create keys.
  • curl, Node.js 20 or later, or Python 3 with requests.

1. Create an API key

  1. In APROS, open Settings → API Keys, select the API keys card, then Create API Key.

  2. Name the key Quickstart. Under Scopes, tick VIEW_LEAD and CREATE_LEAD.

  3. Select Create and copy the key from Your new API Key. It is shown only once.

  4. Put the key and your workspace address in environment variables:

    export APROS_API_KEY="sk-..."
    export APROS_BASE_URL="https://<your-workspace>.apros.app"

Authentication explains scopes, expiry, rotation and revocation in detail.

2. Check the key

GET /api/me/scopes tells you what the key can do. It works with any valid key.

curl "$APROS_BASE_URL/api/me/scopes" \
  -H "Authorization: Bearer $APROS_API_KEY"

effective should contain both scopes:

["CREATE_LEAD", "VIEW_LEAD"]

If it is missing one, your own account does not hold that permission: a key never gets more than its owner. A 401 means the key was mistyped, revoked or has expired.

3. List leads

GET /api/leads returns your leads newest first, one page at a time. Ask for five:

curl "$APROS_BASE_URL/api/leads?pageSize=5" \
  -H "Authorization: Bearer $APROS_API_KEY"

The response, shortened to one lead and a few of its fields:

{
  "items": [
    {
      "id": "8f3c2b7a-1d4e-4f6a-9b2c-3e5d7f9a1b2c",
      "firstName": "Olena",
      "lastName": "Koval",
      "companyName": "Koval Studio",
      "email": "olena@example.com",
      "status": "NEW",
      "temperature": "WARM",
      "score": 42,
      "createdAt": "2026-10-17T14:05:12.000Z"
    }
  ],
  "total": 128,
  "page": 1,
  "pageSize": 5,
  "pageCount": 26
}

You only see the leads your own account can see. To get the next page, add page=2. Filters such as status=QUALIFIED or search=koval narrow the list: see Pagination, filtering and sorting and the List leads reference.

4. Create a lead

POST /api/leads creates a lead. Every field is optional, but give at least a name or a company name. Send an Idempotency-Key header with a fresh UUID: if the network drops the response and you send the same request again, APROS replays the first result instead of creating a second lead.

curl -X POST "$APROS_BASE_URL/api/leads" \
  -H "Authorization: Bearer $APROS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "firstName": "Olena",
    "lastName": "Koval",
    "email": "olena@example.com",
    "phone": "+380671234567",
    "companyName": "Koval Studio"
  }'

A created lead answers 201, with the lead inside data. Shortened:

{
  "success": true,
  "data": {
    "id": "c41e9d02-5b7a-4f3e-8a6d-1f2b3c4d5e6f",
    "firstName": "Olena",
    "lastName": "Koval",
    "email": "olena@example.com",
    "phone": "+380671234567",
    "companyName": "Koval Studio",
    "status": "NEW",
    "ownerId": "5d2e8f14-3a6b-4c7d-9e0f-1a2b3c4d5e6f",
    "createdAt": "2026-10-18T09:30:00.000Z"
  }
}

A few things to know about creating leads:

  • Phone numbers must start with + and the country code, for example +380671234567.
  • Without ownerId, the lead belongs to the person who owns the key.
  • Without stageId, the lead goes to the first stage of the pipeline named in pipelineId, or of your default lead pipeline.
  • Without sourceId, the lead gets your workspace's direct source (named "Direct" unless someone renamed it).
  • You can pass where the lead came from: utmSource, utmMedium, utmCampaign, utmContent, utmTerm, gclid, fbclid, referrer and landingPage. A website form can send these with each lead.
  • If an administrator turned on Merge exact duplicates automatically, a lead with the same email, phone or messenger handle as an existing one may be merged into it straight away. The response then carries the existing lead's ID in data.mergedIntoId.

If something fails

Every error has the same shape, { "error": "...", "code": "..." }. A 400 with VALIDATION_ERROR lists the rejected fields in issues; a 403 with ACCESS_DENIED means the key lacks CREATE_LEAD. See Errors for all of them.

Next steps