---
title: "Speakeroo API Reference: Speech Analysis REST API"
description: "The Speakeroo REST API: analyse recordings and transcripts, read your practice sessions, and fetch topics, pronunciation and filler words with an API key."
url: "https://speakeroo.app/integrations/api"
---

# REST API

Analyse speeches and fetch speaking practice content with a personal Speakeroo API key. Every call takes a personal API key from your profile.

```
https://api.speakeroo.app
```

[Get an API key](https://speakeroo.app/profile) [OpenAPI file](https://speakeroo.app/openapi.json)

## Authentication

Create a key on your [profile](https://speakeroo.app/profile) and send it with every request. The key is shown once and only a hash is stored.

```
Authorization: Bearer spk_user_…
```

Keys start with `spk_user_`. Revoke one from the same card and it stops working immediately.

## Endpoints

POST `/v1/recordings`

### Analyze a recording

Analyze a spoken recording as a Speakeroo session, the same as a recording made in the app: it appears in the learner's history and counts against their plan (Free: 2 sessions a day; Plus: recording minutes). Send the audio as multipart/form-data with a file part, or as JSON with a public https audioUrl: 20-120 seconds of speech, up to 10 MB, as mp3, m4a/mp4, wav, webm, ogg or flac. The audio is fetched and transcribed first; then the call waits up to 30 more seconds for the analysis and answers the session, completed or failed.

Request · `application/json`

```
{
  "audioUrl": "https://example.com/speech.m4a",
  "title": "Team update rehearsal"
}
```

Request · `multipart/form-data`

```
file=@speech.m4a
title=Team update rehearsal
```

200 Response

```
{
  "analysis": {
    "coaching": {
      "deliveryMoments": [
        {
          "description": "The pause before the result lets the number land.",
          "excerpt": "we shipped it. Two days early.",
          "label": "Pause before the result",
          "sentiment": "strength",
          "type": "effective_pause"
        }
      ],
      "feedback": {
        "delivery": "A steady pace with one rushed stretch in the middle.",
        "rhetoric": "The update leads with the result and closes with a clear ask.",
        "weakWords": "Two hedges soften the ask; drop them."
      },
      "rhetoricalDevices": [
        {
          "device": "triad",
          "effect": "Three short wins make the progress easy to remember.",
          "excerpt": "faster builds, fewer bugs, happier customers"
        }
      ],
      "weakWords": [
        {
          "category": "hedging",
          "count": 2,
          "suggestion": "",
          "text": "kind of"
        }
      ]
    },
    "delivery": {
      "fillerWordsPerMinute": 1.4,
      "pace": "steady",
      "pausesPerMinute": 6.2,
      "pitch": {
        "medianHz": 182,
        "rangeSemitones": 7.5
      },
      "vocabularyDiversity": 58,
      "vocalExpression": {
        "level": "expressive",
        "note": "Pitch rises on the key result and settles on the ask."
      },
      "wordsPerMinute": {
        "average": 138,
        "median": 135
      }
    },
    "overallScore": 7,
    "rubric": {
      "areas": [
        {
          "area": "coherence",
          "description": "The update follows result, reasons, then the ask.",
          "examples": [
            {
              "analysis": "Leading with the outcome tells the team why to listen.",
              "quote": "We shipped the new checkout two days early."
            }
          ],
          "recommendation": "Name the ask in the first sentence too.",
          "score": 8,
          "strands": [
            {
              "evidence": "Clear order of points",
              "name": "Structure",
              "score": 8
            }
          ]
        }
      ],
      "summary": {
        "improvements": [
          "Cut the hedges before the ask."
        ],
        "strengths": [
          "Leads with the result."
        ]
      }
    },
    "skillLevel": "intermediate"
  },
  "completedAt": "2026-11-09T18:00:31.000Z",
  "createdAt": "2026-11-09T18:00:00.000Z",
  "durationSeconds": 42,
  "error": null,
  "id": "k975tq3bv6cx2t9tsv4qh2a0n57r4d1e",
  "mode": "recording",
  "source": "api",
  "status": "completed",
  "title": "Team update rehearsal",
  "transcript": "We shipped the new checkout two days early. Faster builds, fewer bugs, happier customers. Next sprint I kind of need two more reviewers.",
  "url": "https://speakeroo.app/session/k975tq3bv6cx2t9tsv4qh2a0n57r4d1e?utm_source=api&utm_medium=api"
}
```

202 Response: The analysis is still running 30 seconds after transcription: the session with status processing. Poll getSession until it is completed or failed.

```
{
  "analysis": null,
  "completedAt": null,
  "createdAt": "2026-11-09T18:00:00.000Z",
  "durationSeconds": 42,
  "error": null,
  "id": "k975tq3bv6cx2t9tsv4qh2a0n57r4d1e",
  "mode": "recording",
  "source": "api",
  "status": "processing",
  "title": "Team update rehearsal",
  "transcript": null,
  "url": "https://speakeroo.app/session/k975tq3bv6cx2t9tsv4qh2a0n57r4d1e?utm_source=api&utm_medium=api"
}
```

POST `/v1/transcripts/analyze`

### Analyze a transcript

Coach a speech from its text: weak and filler words with firmer alternatives, rhetorical devices, delivery and rhetoric feedback, grammar, vocabulary and coherence scores (1-10) on the Speakeroo rubric, and word-level issues with the excerpt and a fix. Text cannot show pace, pauses, pitch or pronunciation. Send 30-1500 words. Counts toward the daily transcript allowance, shared with the other transcript endpoint: 2 a day on Free, 200 on Plus, reset at 00:00 UTC.

Request · `application/json`

```
{
  "transcript": "Good morning everyone. Today I want to talk about why every student should learn to cook. Um, cooking teaches you to plan ahead, to manage your money and, basically, to look after yourself. It is also a great way to bring friends together, so I really believe it belongs in every school.",
  "context": "general",
  "topic": "Should schools teach cooking?"
}
```

200 Response

```
{
  "callToAction": {
    "text": "string",
    "url": "string"
  },
  "coaching": {
    "deliveryMoments": [
      {
        "description": "string",
        "excerpt": "string",
        "label": "string",
        "sentiment": "strength",
        "type": "emphasis"
      }
    ],
    "feedback": {
      "delivery": "string",
      "rhetoric": "string",
      "weakWords": "string"
    },
    "rhetoricalDevices": [
      {
        "device": "rhetorical_question",
        "effect": "string",
        "excerpt": "string"
      }
    ],
    "weakWords": [
      {
        "category": "hedging",
        "count": 0,
        "suggestion": "string",
        "text": "string"
      }
    ]
  },
  "context": "string",
  "issues": [
    {
      "excerpt": "string",
      "explanation": "string",
      "fix": "string",
      "type": "string"
    }
  ],
  "language": {
    "areas": [
      {
        "area": "pacing",
        "description": "string",
        "examples": [
          {
            "analysis": "string",
            "quote": "string"
          }
        ],
        "recommendation": "string",
        "score": 0,
        "strands": [
          {
            "evidence": "string",
            "name": "string",
            "score": 0
          }
        ]
      }
    ],
    "summary": {
      "improvements": [
        "string"
      ],
      "strengths": [
        "string"
      ]
    }
  },
  "unavailable": [
    "string"
  ],
  "wordCount": 0
}
```

POST `/v1/transcripts/refine`

### Restructure a transcript

Rewrite a speech into a clear structure (PREP, STAR, problem-solution, rule of three and others) chosen to fit it. Returns the rewritten sections, the structure with a 1-10 score for how well the original already followed it, a summary of what changed and one delivery tip. Send 30-1500 words. Counts toward the daily transcript allowance, shared with the other transcript endpoint: 2 a day on Free, 200 on Plus, reset at 00:00 UTC.

Request · `application/json`

```
{
  "transcript": "Good morning everyone. Today I want to talk about why every student should learn to cook. Um, cooking teaches you to plan ahead, to manage your money and, basically, to look after yourself. It is also a great way to bring friends together, so I really believe it belongs in every school.",
  "context": "general",
  "topic": "Should schools teach cooking?"
}
```

200 Response

```
{
  "callToAction": {
    "text": "string",
    "url": "string"
  },
  "refinedVersion": {
    "changesSummary": "string",
    "coachingTip": "string",
    "originalWordCount": 0,
    "refinedWordCount": 0,
    "sections": [
      {
        "label": "string",
        "text": "string"
      }
    ],
    "structure": "prep",
    "structureName": "string",
    "structureScore": 0
  },
  "wordCount": 0
}
```

GET `/v1/filler-words`

### List filler words

The common filler words in spoken English grouped by what they do, and the steps to stop using them.

200 Response

```
{
  "groups": [
    {
      "role": "string",
      "words": [
        "string"
      ]
    }
  ],
  "howToStop": [
    {
      "body": "string",
      "step": "string"
    }
  ],
  "link": "string"
}
```

GET `/v1/me`

### Get your account

The learner the API key belongs to and their plan. Use it to check that a key works.

200 Response

```
{
  "id": "string",
  "name": "string",
  "plan": "free"
}
```

GET `/v1/pronunciations/{word}`

### Get how to pronounce a word

How to say an English word Speakeroo has a guide for: IPA, a plain respelling, syllables with the stressed one, sound tips, the usual mistake and two example sentences. A word without a guide answers found: false with guides that start the same way.

`word` path required

200 Response

```
{
  "found": true,
  "ipa": "string",
  "link": "string",
  "note": "string",
  "respelling": "string",
  "sentences": [
    "string"
  ],
  "similarWords": [
    "string"
  ],
  "stressedSyllable": 0,
  "syllables": [
    "string"
  ],
  "tips": [
    {
      "body": "string",
      "heading": "string"
    }
  ],
  "word": "string"
}
```

GET `/v1/rubric`

### Get the speaking rubric

A four-level speaking rubric for speaking homework: fluency, pronunciation, vocabulary range and task completion, with a descriptor for every level.

200 Response

```
{
  "criteria": [
    {
      "levels": [
        {
          "descriptor": "string",
          "level": 0
        }
      ],
      "name": "string"
    }
  ],
  "link": "string",
  "name": "string"
}
```

GET `/v1/sessions`

### List sessions

The learner's sessions, newest first, as their history in the app shows them: every session on Plus, the latest 2 on Free. Pass nextCursor back as cursor for the next page; a page may hold fewer than limit sessions, so keep going while nextCursor is set.

`cursor` querynextCursor from the previous page

`limit` querySessions per page, default 20

200 Response

```
{
  "nextCursor": "string",
  "sessions": [
    {
      "analysis": {
        "coaching": {
          "deliveryMoments": [
            {
              "description": "The pause before the result lets the number land.",
              "excerpt": "we shipped it. Two days early.",
              "label": "Pause before the result",
              "sentiment": "strength",
              "type": "effective_pause"
            }
          ],
          "feedback": {
            "delivery": "A steady pace with one rushed stretch in the middle.",
            "rhetoric": "The update leads with the result and closes with a clear ask.",
            "weakWords": "Two hedges soften the ask; drop them."
          },
          "rhetoricalDevices": [
            {
              "device": "triad",
              "effect": "Three short wins make the progress easy to remember.",
              "excerpt": "faster builds, fewer bugs, happier customers"
            }
          ],
          "weakWords": [
            {
              "category": "hedging",
              "count": 2,
              "suggestion": "",
              "text": "kind of"
            }
          ]
        },
        "delivery": {
          "fillerWordsPerMinute": 1.4,
          "pace": "steady",
          "pausesPerMinute": 6.2,
          "pitch": {
            "medianHz": 182,
            "rangeSemitones": 7.5
          },
          "vocabularyDiversity": 58,
          "vocalExpression": {
            "level": "expressive",
            "note": "Pitch rises on the key result and settles on the ask."
          },
          "wordsPerMinute": {
            "average": 138,
            "median": 135
          }
        },
        "overallScore": 7,
        "rubric": {
          "areas": [
            {
              "area": "coherence",
              "description": "The update follows result, reasons, then the ask.",
              "examples": [
                {
                  "analysis": "Leading with the outcome tells the team why to listen.",
                  "quote": "We shipped the new checkout two days early."
                }
              ],
              "recommendation": "Name the ask in the first sentence too.",
              "score": 8,
              "strands": [
                {
                  "evidence": "Clear order of points",
                  "name": "Structure",
                  "score": 8
                }
              ]
            }
          ],
          "summary": {
            "improvements": [
              "Cut the hedges before the ask."
            ],
            "strengths": [
              "Leads with the result."
            ]
          }
        },
        "skillLevel": "intermediate"
      },
      "completedAt": "2026-11-09T18:00:31.000Z",
      "createdAt": "2026-11-09T18:00:00.000Z",
      "durationSeconds": 42,
      "error": null,
      "id": "k975tq3bv6cx2t9tsv4qh2a0n57r4d1e",
      "mode": "recording",
      "source": "api",
      "status": "completed",
      "title": "Team update rehearsal",
      "transcript": "We shipped the new checkout two days early. Faster builds, fewer bugs, happier customers. Next sprint I kind of need two more reviewers.",
      "url": "https://speakeroo.app/session/k975tq3bv6cx2t9tsv4qh2a0n57r4d1e?utm_source=api&utm_medium=api"
    }
  ]
}
```

GET `/v1/sessions/{id}`

### Get a session

One of the learner's sessions with its transcript and feedback. A session that is not theirs answers 404.

`id` path requiredThe session id

200 Response

```
{
  "analysis": {
    "coaching": {
      "deliveryMoments": [
        {
          "description": "The pause before the result lets the number land.",
          "excerpt": "we shipped it. Two days early.",
          "label": "Pause before the result",
          "sentiment": "strength",
          "type": "effective_pause"
        }
      ],
      "feedback": {
        "delivery": "A steady pace with one rushed stretch in the middle.",
        "rhetoric": "The update leads with the result and closes with a clear ask.",
        "weakWords": "Two hedges soften the ask; drop them."
      },
      "rhetoricalDevices": [
        {
          "device": "triad",
          "effect": "Three short wins make the progress easy to remember.",
          "excerpt": "faster builds, fewer bugs, happier customers"
        }
      ],
      "weakWords": [
        {
          "category": "hedging",
          "count": 2,
          "suggestion": "",
          "text": "kind of"
        }
      ]
    },
    "delivery": {
      "fillerWordsPerMinute": 1.4,
      "pace": "steady",
      "pausesPerMinute": 6.2,
      "pitch": {
        "medianHz": 182,
        "rangeSemitones": 7.5
      },
      "vocabularyDiversity": 58,
      "vocalExpression": {
        "level": "expressive",
        "note": "Pitch rises on the key result and settles on the ask."
      },
      "wordsPerMinute": {
        "average": 138,
        "median": 135
      }
    },
    "overallScore": 7,
    "rubric": {
      "areas": [
        {
          "area": "coherence",
          "description": "The update follows result, reasons, then the ask.",
          "examples": [
            {
              "analysis": "Leading with the outcome tells the team why to listen.",
              "quote": "We shipped the new checkout two days early."
            }
          ],
          "recommendation": "Name the ask in the first sentence too.",
          "score": 8,
          "strands": [
            {
              "evidence": "Clear order of points",
              "name": "Structure",
              "score": 8
            }
          ]
        }
      ],
      "summary": {
        "improvements": [
          "Cut the hedges before the ask."
        ],
        "strengths": [
          "Leads with the result."
        ]
      }
    },
    "skillLevel": "intermediate"
  },
  "completedAt": "2026-11-09T18:00:31.000Z",
  "createdAt": "2026-11-09T18:00:00.000Z",
  "durationSeconds": 42,
  "error": null,
  "id": "k975tq3bv6cx2t9tsv4qh2a0n57r4d1e",
  "mode": "recording",
  "source": "api",
  "status": "completed",
  "title": "Team update rehearsal",
  "transcript": "We shipped the new checkout two days early. Faster builds, fewer bugs, happier customers. Next sprint I kind of need two more reviewers.",
  "url": "https://speakeroo.app/session/k975tq3bv6cx2t9tsv4qh2a0n57r4d1e?utm_source=api&utm_medium=api"
}
```

GET `/v1/topics`

### List speech topics

Random speech topics to practise with: impromptu, persuasive, informative, presentation, IELTS Speaking Part 1 questions or Part 2 cue cards.

`category` query requiredimpromptu persuasive informative presentation ielts_part_1 ielts_part_2

`count` queryHow many topics, default 10

200 Response

```
{
  "category": "impromptu",
  "link": "string",
  "title": "string",
  "topics": [
    {
      "prompts": [
        "string"
      ],
      "section": "string",
      "topic": "string"
    }
  ]
}
```

## Errors

```
{
  "error": {
    "code": "invalid_request",
    "message": "query.count: Too big: expected number to be <=25"
  }
}
```

400 `invalid_request`The request is invalid.

401 `unauthorized`Missing, invalid or revoked API key.

404 `not_found`No such session.

429 `quota_exceeded`Today's allowance is used up.

429 `rate_limited`Too many requests. Retry after the delay in Retry-After.

500 `internal_error`Something went wrong. Try again.

503 `service_unavailable`Speakeroo could not analyse this right now. Please try again in a few minutes.

## Limits

### Rate limit

60 requests a minute per key. Past it, calls answer 429 rate_limited with a Retry-After header in seconds.

### Transcript allowance

2 transcript analyses a day on Free and 200 on Plus, shared by both transcript endpoints and reset at 00:00 UTC. Past it, calls answer 429 quota_exceeded. A call that fails does not count.

### Recordings

Each recording is a session on your plan, as in the app: 2 a day on Free, your recording minutes on Plus. Past it, calls answer 429 quota_exceeded.
