Public API
A directory bots can read
List the catalog, submit a template, add integrations to a bot, add an 𝕏 post to the showcase, or register a webhook for new bots. No API key. The API returns JSON and supports cross-origin requests.
List bots
The published directory as JSON, newest first. CORS is open. No API key.
Request
GET https://grokbots.best/api/bots
Response
| Field | Meaning |
|---|---|
id | Directory id. |
slug | URL slug. |
name | Display name from x.ai. |
description | Short summary from x.ai. |
author | 𝕏 handle, or null. |
url | Directory page, such as https://grokbots.best/bots/… |
source_url | 𝕏 status URL, or null. |
integrations | Integration slugs used by the bot. |
categories | Up to a few directory categories such as Marketing, SEO, or Engineering. |
install_count | Times the bot was added via the site's install action. |
created_at | When it was added. |
[
{
"id": "…",
"slug": "example-bot",
"name": "Example Bot",
"description": "…",
"author": "@handle",
"url": "https://grokbots.best/bots/example-bot",
"source_url": "https://x.com/handle/status/123",
"integrations": ["github"],
"categories": ["Engineering"],
"install_count": 0,
"created_at": "2026-04-01T00:00:00.000Z"
}
]Status 200 is an array of published bots. 500 if the directory fails to load.
Submit a bot
POST a public Grok Bot template link. We fetch the name and description from x.ai, then publish it to the directory. Do not send name or description yourself. x.ai often omits connectors, so you can pass integrations yourself. You can also pass categories.
Request
| Field | Meaning | Required |
|---|---|---|
link | A template URL like https://x.ai/bot/… | yes |
source_url | An 𝕏 status URL. | no |
author | An 𝕏 handle such as @handle. | no |
integrations | Names or slugs such as github. If omitted, we use what we can detect from x.ai. | no |
categories | Up to 3 names such as Engineering or Productivity. If omitted, none are set. | no |
POST https://grokbots.best/api/bots/submit
Content-Type: application/json
{
"link": "https://x.ai/bot/ph5mcXqVy2p176Br7BJYi",
"source_url": "https://x.com/handle/status/123",
"author": "@handle",
"integrations": ["github", "pstack"],
"categories": ["Engineering", "Productivity"]
}Response
| Field | Meaning |
|---|---|
slug | URL slug of the published bot. |
url | Directory path, such as /bots/…. |
{
"slug": "example-bot",
"url": "/bots/example-bot"
}Status 200 with slug and url. 409 if already in the directory. 404 if the template is not on x.ai. 400 for an invalid link, post URL, handle, integrations, or categories. 503 if saving is not configured.
Add integrations
POST names or slugs to add to a published bot. Existing integrations stay. This does not remove any. No API key.
Request
| Field | Meaning | Required |
|---|---|---|
integrations | Names or slugs such as github. Already-listed ones are skipped. At most 24 after the merge. | yes |
POST https://grokbots.best/api/bots/example-bot/integrations
Content-Type: application/json
{
"integrations": ["github", "gmail"]
}Response
| Field | Meaning |
|---|---|
slug | URL slug of the bot. |
url | Directory path, such as /bots/…. |
integrations | All integration slugs on the bot after the merge. |
{
"slug": "example-bot",
"url": "/bots/example-bot",
"integrations": ["gmail", "github"]
}Status 200 with the full list after adding. Duplicates and an empty array leave the bot unchanged. 404 if the bot is not in the directory. 400 for a missing array or a merge that would exceed 24. 503 if saving is not configured.
Add a showcase post
POST a public 𝕏 status URL. We add it to the showcase feed. No API key.
Request
| Field | Meaning | Required |
|---|---|---|
url | An 𝕏 status URL, like https://x.com/user/status/… | yes |
POST https://grokbots.best/api/feed
Content-Type: application/json
{
"url": "https://x.com/handle/status/123"
}Response
| Field | Meaning |
|---|---|
id | Saved post id. |
url | Canonical 𝕏 status URL. |
{
"id": "…",
"url": "https://x.com/handle/status/123"
}Status 200 with id and url. 409 if already in the feed. 400 for an invalid 𝕏 post URL. 503 if saving is not configured.
Add a webhook
POST an HTTPS URL. We ping it and only keep a 2xx response. We don't list saved URLs, so keep a copy to remove it later.
Request
| Field | Meaning | Required |
|---|---|---|
url | An HTTPS endpoint, like https://example.com/hooks/grokbots. | yes |
POST https://grokbots.best/api/webhooks/bots
Content-Type: application/json
{
"url": "https://example.com/hooks/grokbots"
}Response
| Field | Meaning |
|---|---|
id | Saved webhook id. |
url | The canonical HTTPS URL we will POST to. |
{
"id": "…",
"url": "https://example.com/hooks/grokbots"
}Status 200 with id and url. 409 if that URL is already registered. 400 for an invalid URL, a private or local address, or a ping that is not 2xx.
Remove a webhook
DELETE the same URL you registered. Anyone with that URL can remove it.
Request
| Field | Meaning | Required |
|---|---|---|
url | The HTTPS endpoint to stop notifying. | yes |
DELETE https://grokbots.best/api/webhooks/bots
Content-Type: application/json
{
"url": "https://example.com/hooks/grokbots"
}Response
| Field | Meaning |
|---|---|
url | The URL we removed. |
{
"url": "https://example.com/hooks/grokbots"
}Status 200 with url. 404 if nothing is registered at that URL. 400 for an invalid URL.
Send this page to a bot
This page documents the public endpoints. Give a bot https://grokbots.best/api and ask it to list the directory, submit a template, add integrations, add a showcase post, or register a webhook.