# BotTalk Publishers API

## API documentation redirect

> Redirects to the API documentation page

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[],"paths":{"/api":{"get":{"summary":"API documentation redirect","description":"Redirects to the API documentation page","operationId":"apiRedirect","responses":{"302":{"description":"Redirect to https://bottalk.io/docs/api/"}}}}}}
```

## List articles

> Returns a paginated list of articles for the authenticated project. Deleted articles are excluded.

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"ArticleListItem":{"type":"object","description":"Abbreviated article object returned in list responses","properties":{"id":{"type":"string"},"external_id":{"type":"string","nullable":true},"title":{"type":"string"},"text":{"type":"string"},"added":{"type":"integer"},"updated":{"type":"integer","nullable":true},"status":{"type":"string"},"url":{"type":"string","nullable":true},"isRaw":{"type":"boolean"},"voice":{"type":"string"},"lang":{"type":"string"},"audio":{"type":"string","nullable":true},"audio_duration":{"type":"number","nullable":true},"audio_preview":{"type":"string","nullable":true},"audio_preview_duration":{"type":"number","nullable":true}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles":{"get":{"summary":"List articles","description":"Returns a paginated list of articles for the authenticated project. Deleted articles are excluded.","operationId":"getArticles","parameters":[{"name":"limit","in":"query","description":"Number of articles to return (min 10, max 100)","schema":{"type":"integer","minimum":10,"maximum":100,"default":10}},{"name":"offset","in":"query","description":"Number of articles to skip","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"List of articles","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"count":{"type":"integer"},"articles":{"type":"array","items":{"$ref":"#/components/schemas/ArticleListItem"}}}}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Create article

> Creates a new article and queues it for audio generation.\
> Requires a full API token (not readonly).\
> If \`externalId\` is provided it must be unique across all articles.<br>

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"ArticleCreateRequest":{"type":"object","required":["title","text"],"properties":{"title":{"type":"string","description":"Article title"},"text":{"type":"string","description":"Article body text (HTML allowed if parse=true)"},"url":{"type":"string","description":"Original article URL"},"externalId":{"type":"string","description":"Unique ID for external control. If an article with this ID already exists, a 400 error is returned."},"voice":{"type":"string","description":"TTS voice name. Must be used together with `lang`.\nAvailable voices: `echo`, `fable`, `alloy`, `onyx`, `nova`, `shimmer` (support `de-DE`, `en-US`),\n`de-DE-ConradNeural`, `de-DE-KatjaNeural` (support `de-DE`)\n"},"lang":{"type":"string","description":"Voice language/locale. Must be used together with `voice`.\nExamples: `de-DE`, `en-US`\n"},"parse":{"type":"boolean","description":"If true, HTML is stripped and text is cleaned before processing","default":false},"isRaw":{"type":"boolean","description":"If true, text is treated as raw (no additional processing)","default":false},"prompt":{"type":"string","description":"Individual prompt for audio generation (valid for Gemini Vertex model)"},"labels":{"type":"array","description":"List of labels to attach to this article","items":{"type":"string"}}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles":{"post":{"summary":"Create article","description":"Creates a new article and queues it for audio generation.\nRequires a full API token (not readonly).\nIf `externalId` is provided it must be unique across all articles.\n","operationId":"createArticle","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleCreateRequest"}}}},"responses":{"200":{"description":"Article created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"id":{"type":"string","description":"Slug of the newly created article"}}}}}},"400":{"description":"Validation error or duplicate externalId","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Get article by ID

> Returns full article details by its internal slug ID.

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"Article":{"type":"object","properties":{"id":{"type":"string","description":"Article slug (internal ID)"},"externalId":{"type":"string","nullable":true,"description":"Unique ID for external control. If an article with this ID already exists, a 400 error is returned."},"title":{"type":"string"},"text":{"type":"string"},"prompt":{"type":"string","nullable":true,"description":"Individual prompt for audio generation (valid for Gemini Vertex model)"},"added":{"type":"integer","description":"Unix timestamp when article was created"},"updated":{"type":"integer","nullable":true,"description":"Unix timestamp of last processing"},"status":{"type":"string","enum":["waiting","processing","ready","errored","deleted","retry","fallback","no_money","limit_reached","rejected","parsed","recrawling"],"description":"Article processing status:\n- `ready` — article is ready and audio file exists\n- `processing` — audification is in progress\n- `waiting` — article is waiting to be audified\n- `retry` — TTS provider returned an error, will retry automatically\n- `rejected` — article rejected by audio automation rules\n- `errored` — error which prevented audification\n- `deleted` — article has been deleted\n- `fallback` — using fallback TTS provider\n- `no_money` — insufficient balance\n- `limit_reached` — daily article limit reached\n- `parsed` — article parsed, awaiting audification\n- `recrawling` — article content is being re-fetched\n"},"url":{"type":"string","nullable":true,"description":"Original article URL"},"isRaw":{"type":"boolean","description":"Whether article text is raw (no HTML stripping)"},"voice":{"type":"string","description":"TTS voice name. Available voices:\n`echo`, `fable`, `alloy`, `onyx`, `nova`, `shimmer` (support `de-DE`, `en-US`),\n`de-DE-ConradNeural`, `de-DE-KatjaNeural` (support `de-DE`)\n"},"lang":{"type":"string","description":"Voice language/locale. Must match the selected voice.\nExamples: `de-DE`, `en-US`\n"},"type":{"type":"array","nullable":true,"description":"Content type scores from comprehend analysis (only if detected)","items":{"type":"object","properties":{"Name":{"type":"string"},"Score":{"type":"number","format":"float"}}}},"audio":{"type":"string","nullable":true,"description":"Full audio MP3 URL (only when ready)"},"audio_duration":{"type":"number","nullable":true,"description":"Full audio duration in seconds"},"audio_preview":{"type":"string","nullable":true,"description":"Preview audio MP3 URL (only when ready)"},"audio_preview_duration":{"type":"number","nullable":true,"description":"Preview audio duration in seconds"},"error":{"type":"string","nullable":true,"description":"Last error message (only when status=errored)"},"errors":{"type":"array","nullable":true,"description":"Error history (only when status=errored)","items":{"type":"object","properties":{"error":{"type":"string"},"date":{"type":"string","format":"date-time"}}}}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles/{articleId}":{"get":{"summary":"Get article by ID","description":"Returns full article details by its internal slug ID.","operationId":"getArticle","parameters":[{"name":"articleId","in":"path","required":true,"description":"Article slug (internal ID returned on create)","schema":{"type":"string"}}],"responses":{"200":{"description":"Article found","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"article":{"$ref":"#/components/schemas/Article"}}}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"200 (not found)":{"description":"Article not found (returns 200 with error result)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Update article by ID

> Updates article content and triggers audio re-generation.\
> Requires a full API token (not readonly).\
> Labels are fully replaced — any existing labels not present in the request will be removed.<br>

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"ArticleUpdateRequest":{"type":"object","required":["title","text"],"properties":{"title":{"type":"string"},"text":{"type":"string"},"url":{"type":"string"},"externalId":{"type":"string","description":"Update the external ID (must be unique)"},"voice":{"type":"string"},"lang":{"type":"string"},"parse":{"type":"boolean","default":false},"isRaw":{"type":"boolean"},"prompt":{"type":"string","nullable":true,"description":"Individual prompt for audio generation (valid for Gemini Vertex model). Set to null to remove."},"labels":{"type":"array","description":"Full replacement of labels (existing labels not in list will be removed)","items":{"type":"string"}}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles/{articleId}":{"put":{"summary":"Update article by ID","description":"Updates article content and triggers audio re-generation.\nRequires a full API token (not readonly).\nLabels are fully replaced — any existing labels not present in the request will be removed.\n","operationId":"updateArticle","parameters":[{"name":"articleId","in":"path","required":true,"description":"Article slug (internal ID)","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleUpdateRequest"}}}},"responses":{"200":{"description":"Article updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"id":{"type":"string"}}}}}},"400":{"description":"Validation error or duplicate externalId","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"401":{"description":"Article belongs to a different project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Delete article

> Marks the article as deleted. Deleted articles are excluded from list responses.\
> Requires a full API token (not readonly).<br>

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"SuccessResult":{"type":"object","properties":{"result":{"type":"string","enum":["ok"]}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles/{articleId}":{"delete":{"summary":"Delete article","description":"Marks the article as deleted. Deleted articles are excluded from list responses.\nRequires a full API token (not readonly).\n","operationId":"deleteArticle","parameters":[{"name":"articleId","in":"path","required":true,"description":"Article slug (internal ID)","schema":{"type":"string"}}],"responses":{"200":{"description":"Article deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResult"}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"404":{"description":"Article not found or already deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Get article by external ID

> Returns full article details by the external ID you provided on creation.

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"Article":{"type":"object","properties":{"id":{"type":"string","description":"Article slug (internal ID)"},"externalId":{"type":"string","nullable":true,"description":"Unique ID for external control. If an article with this ID already exists, a 400 error is returned."},"title":{"type":"string"},"text":{"type":"string"},"prompt":{"type":"string","nullable":true,"description":"Individual prompt for audio generation (valid for Gemini Vertex model)"},"added":{"type":"integer","description":"Unix timestamp when article was created"},"updated":{"type":"integer","nullable":true,"description":"Unix timestamp of last processing"},"status":{"type":"string","enum":["waiting","processing","ready","errored","deleted","retry","fallback","no_money","limit_reached","rejected","parsed","recrawling"],"description":"Article processing status:\n- `ready` — article is ready and audio file exists\n- `processing` — audification is in progress\n- `waiting` — article is waiting to be audified\n- `retry` — TTS provider returned an error, will retry automatically\n- `rejected` — article rejected by audio automation rules\n- `errored` — error which prevented audification\n- `deleted` — article has been deleted\n- `fallback` — using fallback TTS provider\n- `no_money` — insufficient balance\n- `limit_reached` — daily article limit reached\n- `parsed` — article parsed, awaiting audification\n- `recrawling` — article content is being re-fetched\n"},"url":{"type":"string","nullable":true,"description":"Original article URL"},"isRaw":{"type":"boolean","description":"Whether article text is raw (no HTML stripping)"},"voice":{"type":"string","description":"TTS voice name. Available voices:\n`echo`, `fable`, `alloy`, `onyx`, `nova`, `shimmer` (support `de-DE`, `en-US`),\n`de-DE-ConradNeural`, `de-DE-KatjaNeural` (support `de-DE`)\n"},"lang":{"type":"string","description":"Voice language/locale. Must match the selected voice.\nExamples: `de-DE`, `en-US`\n"},"type":{"type":"array","nullable":true,"description":"Content type scores from comprehend analysis (only if detected)","items":{"type":"object","properties":{"Name":{"type":"string"},"Score":{"type":"number","format":"float"}}}},"audio":{"type":"string","nullable":true,"description":"Full audio MP3 URL (only when ready)"},"audio_duration":{"type":"number","nullable":true,"description":"Full audio duration in seconds"},"audio_preview":{"type":"string","nullable":true,"description":"Preview audio MP3 URL (only when ready)"},"audio_preview_duration":{"type":"number","nullable":true,"description":"Preview audio duration in seconds"},"error":{"type":"string","nullable":true,"description":"Last error message (only when status=errored)"},"errors":{"type":"array","nullable":true,"description":"Error history (only when status=errored)","items":{"type":"object","properties":{"error":{"type":"string"},"date":{"type":"string","format":"date-time"}}}}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles_external_id/{externalId}":{"get":{"summary":"Get article by external ID","description":"Returns full article details by the external ID you provided on creation.","operationId":"getArticleByExternalId","parameters":[{"name":"externalId","in":"path","required":true,"description":"Your external article identifier","schema":{"type":"string"}}],"responses":{"200":{"description":"Article found","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"article":{"$ref":"#/components/schemas/Article"}}}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"200 (not found)":{"description":"Article not found (returns 200 with error result)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Update article by external ID

> Updates article by external ID and triggers audio re-generation.\
> Requires a full API token (not readonly).<br>

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"ArticleUpdateRequest":{"type":"object","required":["title","text"],"properties":{"title":{"type":"string"},"text":{"type":"string"},"url":{"type":"string"},"externalId":{"type":"string","description":"Update the external ID (must be unique)"},"voice":{"type":"string"},"lang":{"type":"string"},"parse":{"type":"boolean","default":false},"isRaw":{"type":"boolean"},"prompt":{"type":"string","nullable":true,"description":"Individual prompt for audio generation (valid for Gemini Vertex model). Set to null to remove."},"labels":{"type":"array","description":"Full replacement of labels (existing labels not in list will be removed)","items":{"type":"string"}}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles_external_id/{externalId}":{"put":{"summary":"Update article by external ID","description":"Updates article by external ID and triggers audio re-generation.\nRequires a full API token (not readonly).\n","operationId":"updateArticleByExternalId","parameters":[{"name":"externalId","in":"path","required":true,"description":"Your external article identifier","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArticleUpdateRequest"}}}},"responses":{"200":{"description":"Article updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"id":{"type":"string"}}}}}},"400":{"description":"Validation error or duplicate externalId","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"404":{"description":"Article not found by externalId","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```

## Get article by URL

> Returns full article details by the original article URL.

```json
{"openapi":"3.0.3","info":{"title":"BotTalk Publishers API","version":"1.0.0"},"servers":[{"url":"https://bottalk.io","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token from project settings"}},"schemas":{"Article":{"type":"object","properties":{"id":{"type":"string","description":"Article slug (internal ID)"},"externalId":{"type":"string","nullable":true,"description":"Unique ID for external control. If an article with this ID already exists, a 400 error is returned."},"title":{"type":"string"},"text":{"type":"string"},"prompt":{"type":"string","nullable":true,"description":"Individual prompt for audio generation (valid for Gemini Vertex model)"},"added":{"type":"integer","description":"Unix timestamp when article was created"},"updated":{"type":"integer","nullable":true,"description":"Unix timestamp of last processing"},"status":{"type":"string","enum":["waiting","processing","ready","errored","deleted","retry","fallback","no_money","limit_reached","rejected","parsed","recrawling"],"description":"Article processing status:\n- `ready` — article is ready and audio file exists\n- `processing` — audification is in progress\n- `waiting` — article is waiting to be audified\n- `retry` — TTS provider returned an error, will retry automatically\n- `rejected` — article rejected by audio automation rules\n- `errored` — error which prevented audification\n- `deleted` — article has been deleted\n- `fallback` — using fallback TTS provider\n- `no_money` — insufficient balance\n- `limit_reached` — daily article limit reached\n- `parsed` — article parsed, awaiting audification\n- `recrawling` — article content is being re-fetched\n"},"url":{"type":"string","nullable":true,"description":"Original article URL"},"isRaw":{"type":"boolean","description":"Whether article text is raw (no HTML stripping)"},"voice":{"type":"string","description":"TTS voice name. Available voices:\n`echo`, `fable`, `alloy`, `onyx`, `nova`, `shimmer` (support `de-DE`, `en-US`),\n`de-DE-ConradNeural`, `de-DE-KatjaNeural` (support `de-DE`)\n"},"lang":{"type":"string","description":"Voice language/locale. Must match the selected voice.\nExamples: `de-DE`, `en-US`\n"},"type":{"type":"array","nullable":true,"description":"Content type scores from comprehend analysis (only if detected)","items":{"type":"object","properties":{"Name":{"type":"string"},"Score":{"type":"number","format":"float"}}}},"audio":{"type":"string","nullable":true,"description":"Full audio MP3 URL (only when ready)"},"audio_duration":{"type":"number","nullable":true,"description":"Full audio duration in seconds"},"audio_preview":{"type":"string","nullable":true,"description":"Preview audio MP3 URL (only when ready)"},"audio_preview_duration":{"type":"number","nullable":true,"description":"Preview audio duration in seconds"},"error":{"type":"string","nullable":true,"description":"Last error message (only when status=errored)"},"errors":{"type":"array","nullable":true,"description":"Error history (only when status=errored)","items":{"type":"object","properties":{"error":{"type":"string"},"date":{"type":"string","format":"date-time"}}}}}},"ErrorResult":{"type":"object","properties":{"result":{"type":"string","enum":["error","fail"]},"message":{"type":"string"}}}}},"paths":{"/api/articles_external_url/{externalUrl}":{"get":{"summary":"Get article by URL","description":"Returns full article details by the original article URL.","operationId":"getArticleByExternalUrl","parameters":[{"name":"externalUrl","in":"path","required":true,"description":"Original article URL (URL-encoded)","schema":{"type":"string"}}],"responses":{"200":{"description":"Article found","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string"},"article":{"$ref":"#/components/schemas/Article"}}}}}},"403":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}},"200 (not found)":{"description":"Article not found (returns 200 with error result)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResult"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bottalk.io/docs/api/bottalk-publishers-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
