Quickstart

From a key to finished minutes, in five steps and one language of your choosing.

  1. 01

    Get a key

    For an organisation's integration, an administrator creates an integration in NotulAI under Koppelingen and issues a key on it. For your own automation, you create a personal key on your own account page, when your organisation has that enabled; it acts as you and sees what you see. Either way the key is shown once. Store it the way you store a password, and never in a browser or a mobile app.

  2. 02

    Check that it works

    Every call goes to https://api.notulai.nl with the key in the Authorization header. Listing meetings is the cheapest way to confirm the key, the scope and the network path in one go.

    curl -X GET 'https://api.notulai.nl/v1/meetings?limit=25' \
      -H 'Authorization: Bearer nla_live_...'
  3. 03

    Create a meeting

    A title and a date are enough. Pass external_id to carry your own reference: repeating the call with the same value returns the meeting you already made instead of a second one, so a retry after a lost response is harmless.

    curl -X POST 'https://api.notulai.nl/v1/meetings' \
      -H 'Authorization: Bearer nla_live_...' \
      -H 'Content-Type: application/json' \
      -d '{
      "date": "2026-09-01",
      "external_id": "CRM-4821",
      "participant_ids": [
        "emp_2f1c9a",
        "emp_7d4b02"
      ],
      "project_id": "proj_5b28e4",
      "shared_with": [
        "emp_2f1c9a"
      ],
      "template_id": "tpl_9c31a7",
      "time": "09:30",
      "title": "Weekly stand-up",
      "visibility": "organisation"
    }'
  4. 04

    Ask where to put the audio

    Name the file's MIME type and you get back an upload_url that is signed for exactly that type, plus how long it stays valid.

    curl -X POST 'https://api.notulai.nl/v1/meetings/mtg_b39d31c7/upload-url' \
      -H 'Authorization: Bearer nla_live_...' \
      -H 'Content-Type: application/json' \
      -d '{
      "content_type": "audio/mpeg"
    }'
  5. 05

    Upload the file

    Now PUT the file straight to that URL. This is the one call that does not go to api.notulai.nl: the audio goes to storage directly, so it never passes through this API. Send no Authorization header, because the signed URL already carries its own, and send the same Content-Type you asked the URL for. The meeting moves to audio_uploaded by itself.

    # UPLOAD_URL is the upload_url from the previous response.
    curl -X PUT "$UPLOAD_URL" \
      -H 'Content-Type: audio/mpeg' \
      --data-binary '@meeting.mp3'
  6. 06

    Wait, then collect

    Transcription and minutes run in the background. Poll the meeting until its status is minutes_ready, then fetch the minutes. Thirty seconds between polls is plenty.

    curl -X GET 'https://api.notulai.nl/v1/meetings/mtg_b39d31c7' \
      -H 'Authorization: Bearer nla_live_...'

Uploading is the one call that leaves the envelope

The URL is signed for the exact Content-Type you asked it for. Send a different one and storage rejects the signature with an XML body instead of our error envelope. See from audio to minutes.

Where to go next