Skip to content

Get started

Quickstart

From nothing to a working integration: create a scoped key, read your contacts, create a deal, and get told when it moves. About five minutes.

Before you begin

  • A Nextora workspace. Its address is where you sign in, for example https://acme.nextora.co. Type yours into the Workspace field in the sidebar — every sample on these pages follows.
  • Access to Settings → Developers in the app, which workspace admins and roles with settings access have.
  • cURL, Node.js 18 or later, or Python 3 with requests. The JavaScript samples use fetch and top-level await: run them as an ES module (.mjs).
  1. Create an API key

    In Nextora, open Settings → Developers → API keys and choose Create key. Name it after the integration, and give it only what it needs — for this guide, Contacts (read), Deals (write) and Webhooks (write).

    Copy the key when it appears: it starts with sk_live_ and is shown only once. Keep it in an environment variable, never in code:

    export NEXTORA_API_KEY="sk_live_…"
  2. Make your first request

    List two contacts. The key goes in the Authorization header as a bearer token:

    List contacts
    curl -G https://acme.nextora.co/api/v1/contacts \
      -H "Authorization: Bearer $NEXTORA_API_KEY" \
      -d limit=2
    Response200 OK
    {
      "data": [
        {
          "id": "3f1c9a7e-2b4d-4c8e-9f60-1a2b3c4d5e6f",
          "first_name": "Ada",
          "last_name": "Brennan",
          "full_name": "Ada Brennan",
          "email": "[email protected]",
          "phone": "+44 20 7946 0958",
          "position": "Head of Operations",
          "company_id": "2b7e4c9a-5d1f-4a8e-9b3c-7f0a1d2e4c56",
          "company": {
            "id": "2b7e4c9a-5d1f-4a8e-9b3c-7f0a1d2e4c56",
            "name": "Northwind Analytics"
          },
          "owner_id": "0c4f8e2a-7b3d-4a1f-9e6c-5d2b8a1f3e47",
          "tags": [
            "enterprise",
            "renewal-2027"
          ],
          "source": "website",
          "custom_fields": {
            "region": "emea"
          },
          "last_activity_at": "2026-10-08T14:12:09Z",
          "created_at": "2026-09-14T09:30:00Z",
          "updated_at": "2026-10-08T14:12:09Z"
        }
      ],
      "meta": {
        "limit": 2,
        "has_more": true,
        "next_cursor": "eyJpZCI6IjNmMWM5YTdlIiwiY3JlYXRlZF9hdCI6IjIwMjYtMDktMTRUMDk6MzA6MDBaIn0"
      }
    }

    Every list looks like this: records in data, paging in meta. Pass meta.next_cursor as cursor for the next page — see Pagination. A 401 means the key is missing or wrong; the error body says which.

  3. Create a deal

    Create a deal for the contact you just read. The Idempotency-Key header makes the request safe to retry: send it again with the same key and you get the same deal back instead of a second one.

    Create a deal
    curl -X POST https://acme.nextora.co/api/v1/deals \
      -H "Authorization: Bearer $NEXTORA_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 0f1e2d3c-4b5a-4987-8a6b-5c4d3e2f1a0b" \
      -d '{
        "title": "Northwind Analytics — annual plan",
        "value": 24000,
        "currency": "EUR",
        "contact_id": "3f1c9a7e-2b4d-4c8e-9f60-1a2b3c4d5e6f",
        "company_id": "2b7e4c9a-5d1f-4a8e-9b3c-7f0a1d2e4c56",
        "expected_close_date": "2026-11-27"
      }'
    Response201 Created
    {
      "data": {
        "id": "8f2d6c1a-4b7e-4f0a-9c3d-2e1b5a6f7c80",
        "title": "Northwind Analytics — annual plan",
        "value": 24000,
        "currency": "EUR",
        "status": "in_progress",
        "pipeline": {
          "id": "9d4b2f7a-3c8e-4b1d-a6f2-5e7c9b0d1a34",
          "name": "New business"
        },
        "stage": {
          "id": "4e8a1c6d-9b2f-4d7a-8c3e-1f5b7a9d0c62",
          "name": "Qualification",
          "type": "open"
        },
        "pipeline_id": "9d4b2f7a-3c8e-4b1d-a6f2-5e7c9b0d1a34",
        "stage_id": "4e8a1c6d-9b2f-4d7a-8c3e-1f5b7a9d0c62",
        "probability": 20,
        "expected_close_date": "2026-11-27",
        "closed_at": null,
        "forecast_category": null,
        "loss_reason": null,
        "competitor": null,
        "contact_id": "3f1c9a7e-2b4d-4c8e-9f60-1a2b3c4d5e6f",
        "company_id": "2b7e4c9a-5d1f-4a8e-9b3c-7f0a1d2e4c56",
        "owner_id": "0c4f8e2a-7b3d-4a1f-9e6c-5d2b8a1f3e47",
        "custom_fields": {},
        "created_at": "2026-10-01T10:12:00Z",
        "updated_at": "2026-10-01T10:12:00Z"
      }
    }

    Without pipeline_id and stage_id, the deal lands in the first stage of the default pipeline. Open the pipeline in Nextora and it is there. Deals need the Sales hub in the plan; without it this request returns 403 hub_not_in_plan.

  4. Get told when it moves

    Subscribe an HTTPS endpoint of yours to deal.stage_changed. The response carries the signing secret — the only time you see it.

    Create a webhook subscription
    curl -X POST https://acme.nextora.co/api/v1/webhooks \
      -H "Authorization: Bearer $NEXTORA_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Quickstart",
        "url": "https://hooks.example.com/nextora",
        "events": [
          "deal.stage_changed"
        ]
      }'
    Response201 Created
    {
      "data": {
        "id": "f3a5c7e9-2b4d-4f6a-8c1e-5d7f9b1a3c60",
        "name": "Quickstart",
        "url": "https://hooks.example.com/nextora",
        "events": [
          "deal.stage_changed"
        ],
        "is_active": true,
        "paused_at": null,
        "paused_reason": null,
        "failing_since": null,
        "last_success_at": null,
        "last_failure_at": null,
        "created_at": "2026-10-10T09:00:00Z",
        "updated_at": "2026-10-10T09:00:00Z",
        "secret": "whsec_9f3b7c1e5a2d8f4b6c0e3a7d1f5b9c2e8a4d6f0b3c7e1a5d"
      }
    }

    Now drag the deal to another stage in the app. Within seconds your endpoint receives a signed POST with the deal and its previous stage. Verify the signature before you trust it, and answer 2xx within 10 seconds.

Conventions

Every endpoint follows the same rules, so one small client covers the whole API.

Rule
Base URLhttps://acme.nextora.co/api/v1. On a custom domain, https://<your domain>/api/v1. HTTPS only.
FormatJSON in and out, UTF-8. Send Content-Type: application/json with a body.
Namessnake_case everywhere: expected_close_date, custom_fields.
IDsUUID strings.
TimeTimestamps in ISO 8601, UTC: 2026-10-10T09:15:02Z. Dates as YYYY-MM-DD.
ResponsesOne record in data; lists in data with paging in meta. Errors in error — see Errors.
UpdatesPATCH and PUT both change only the fields you send. Unknown fields in a body are ignored.
DeletesMove records to Trash; POST …/{id}/restore brings them back.
BrowsersNo CORS: call the API from your server, and never ship a key to a browser or an app.

Next steps