> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aigenda.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> From a token to a finished protocol in six requests.

Let's walk through the whole flow with a short file, `standup.mp3`. You need `curl` and [`jq`](https://jqlang.org) to parse JSON.

<Steps>
  <Step title="Get a token">
    Send the email and password of your AiGenda account. The response contains a pair of tokens, and you need `access` for requests.

    ```bash theme={null}
    export AIGENDA_EMAIL="you@example.com"
    export AIGENDA_PASSWORD="your-password"

    TOKEN=$(curl -s -X POST https://api.aigenda.tech/api/token/ \
      -H "Content-Type: application/json" \
      -d "{\"username\": \"$AIGENDA_EMAIL\", \"password\": \"$AIGENDA_PASSWORD\"}" \
      | jq -r .access)
    ```

    The field is called `username`, but it holds your email. Learn more: [Authentication](/en/authentication).
  </Step>

  <Step title="Find your space_id">
    Recordings live in spaces. Take your personal space, it has `is_main_space: true`.

    ```bash theme={null}
    SPACE_ID=$(curl -s "https://api.aigenda.tech/api/spaces/?limit=50&offset=0" \
      -H "Authorization: Bearer $TOKEN" \
      | jq -r '.results[] | select(.is_main_space) | .space.id')
    ```
  </Step>

  <Step title="Create a recording">
    Pass the title, the exact file size in bytes, and the MIME type. The title must end with the file extension.

    ```bash theme={null}
    FILE=standup.mp3
    SIZE=$(wc -c < "$FILE" | tr -d ' ')

    CREATED=$(curl -s -X POST "https://api.aigenda.tech/api/spaces/$SPACE_ID/audio/" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d "{\"title\": \"$FILE\", \"size\": $SIZE, \"content_type\": \"audio/mpeg\"}")

    AUDIO_ID=$(echo "$CREATED" | jq -r .id)
    UPLOAD_URL=$(echo "$CREATED" | jq -r '.url[0]')
    ```

    `url` contains an array of upload links, one per file part of about 10 MB. In this quickstart you send the whole file to the first link and complete the upload with a single part. For a production integration, upload in parts, see [Uploading a file](/en/upload/file).
  </Step>

  <Step title="Upload the file and complete the upload">
    Send the file to the link with `PUT` and save the `ETag` header from the response. Then tell AiGenda that the upload is finished.

    ```bash theme={null}
    ETAG=$(curl -s -X PUT "$UPLOAD_URL" --upload-file "$FILE" -D - -o /dev/null \
      | grep -i '^etag:' | cut -d' ' -f2 | tr -d '\r')

    curl -s -X POST "https://api.aigenda.tech/api/spaces/$SPACE_ID/audio/$AUDIO_ID/complete_upload/" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d "$(jq -n --arg etag "$ETAG" '{parts: [{PartNumber: 1, ETag: $etag}]}')"

    until curl -s "https://api.aigenda.tech/api/spaces/$SPACE_ID/audio/$AUDIO_ID/info/" \
      -H "Authorization: Bearer $TOKEN" | jq -e .is_uploaded > /dev/null; do sleep 2; done
    ```

    `ETag` comes wrapped in double quotes, and you must pass it as is. The loop at the end waits until AiGenda confirms the file (`is_uploaded: true`).
  </Step>

  <Step title="Start processing">
    ```bash theme={null}
    curl -s -X POST https://api.aigenda.tech/api/audio/classify/ \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d "{\"audio_id\": $AUDIO_ID}"
    ```

    At this point the plan is charged minutes for the recording's duration.
  </Step>

  <Step title="Fetch the protocol">
    Poll the result every 15 seconds until you get `classified: true`. If `success` is `false` at that point, processing failed.

    ```bash theme={null}
    while true; do
      RESULT=$(curl -s "https://api.aigenda.tech/api/spaces/$SPACE_ID/audio/$AUDIO_ID/result/" \
        -H "Authorization: Bearer $TOKEN")
      echo "$RESULT" | jq -e '.classified == true' > /dev/null 2>&1 && break
      sleep 15
    done

    echo "$RESULT" | jq -r .result.protocol > protocol.md
    ```

    Done: the meeting protocol is in `protocol.md`.
  </Step>
</Steps>

<Warning>
  This loop cannot tell failed processing from processing in progress, so it will wait forever. In a production integration, handle errors following the rules on the [Status and polling](/en/processing/status) page.
</Warning>

## What's next

<CardGroup cols={2}>
  <Card title="Uploading large files" icon="upload" href="/en/upload/file">
    Uploading in parts, code in Python and JavaScript.
  </Card>

  <Card title="Result structure" icon="file-text" href="/en/processing/result">
    Protocol, utterances, speakers.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.