crob.at

Share Pokémon teams for free

API Documentation

REST API for team storage, random generation, and authenticated Showdown helpers

Endpoints

GET /api/team/:slug

Retrieve a team by its slug.

Example:

curl https://crob.at/api/team/abc123
const response = await fetch('https://crob.at/api/team/abc123');
const data = await response.json();
console.log(data);
import requests

response = requests.get('https://crob.at/api/team/abc123')
data = response.json()
print(data)

Response:

{
  "slug": "abc123",
  "name": "My Team",
  "author": "username",
  "is_multi": false,
  "teams": [{"paste": "..."}]
}

POST /api/team

Create a new team.

Request:

{
  "name": "My Team Name",
  "author": "username",
  "teams": [{
    "paste": "Garchomp @ Choice Scarf\nAbility: Rough Skin\n..."
  }]
}

Example:

curl -X POST https://crob.at/api/team \
  -H "Content-Type: application/json" \
  -d '{"name": "My Team", "teams": [{"paste": "Garchomp @ Choice Scarf\n..."}]}'
const response = await fetch('https://crob.at/api/team', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    name: 'My Team',
    teams: [{paste: 'Garchomp @ Choice Scarf\n...'}]
  })
});

const {slug, url} = await response.json();
console.log(`Created: ${url}`);
import requests

response = requests.post('https://crob.at/api/team', json={
    'name': 'My Team',
    'teams': [{'paste': 'Garchomp @ Choice Scarf\n...'}]
})

data = response.json()
print(f"Created: {data['url']}")

Response:

{
  "slug": "abc123",
  "url": "https://crob.at/abc123"
}

GET /api/random-team/:format

Generate a random competitive team for a Smogon format. Returns the Showdown export, rendered card HTML used by the site UI, and saved page/image URLs for the generated team.

Example:

curl https://crob.at/api/random-team/gen9ou
const response = await fetch('https://crob.at/api/random-team/gen9ou');
const data = await response.json();
console.log(data.teamText);
import requests

response = requests.get('https://crob.at/api/random-team/gen9ou')
data = response.json()
print(data['teamText'])

Response:

{
  "slug": "abc123",
  "url": "https://crob.at/abc123",
  "image": "https://crob.at/og/abc123.png",
  "teamText": "Gholdengo @ Leftovers\n...",
  "statsDate": "2026-03",
  "cardsHtml": "<div class=\"pokemon-grid\">...</div>"
}

GET /api/samples/:tier

Return Smogon sample teams for a given tier (format). Results are cached for one hour.

Example:

curl https://crob.at/api/samples/gen9ou
const response = await fetch('https://crob.at/api/samples/gen9ou');
const teams = await response.json();
console.log(teams[0].name);
import requests

response = requests.get('https://crob.at/api/samples/gen9ou')
teams = response.json()
print(teams[0]['name'])

Response:

[
  {
    "slug": "abc123",
    "name": "Sun Offense",
    "author": "Smogon",
    "tier": "gen9ou",
    "views": 142,
    "created_at": "2026-01-15 10:00:00",
    "url": "https://crob.at/abc123",
    "image": "https://crob.at/og/abc123.png",
    "source_url": "https://www.smogon.com/forums/..."
  }
]

Returns 400 if :tier contains non-alphanumeric characters. Returns an empty array if no sample teams exist for that tier.

GET /api/me

Return the currently authenticated crob.at user, if any. This endpoint is intended for same-origin session-aware UI.

Example:

curl https://crob.at/api/me \
  -H "Cookie: session=your-session-cookie"
const response = await fetch('https://crob.at/api/me', {
  credentials: 'include'
});

const data = await response.json();
console.log(data.user);
import requests

session = requests.Session()
session.cookies.set('session', 'your-session-cookie')

response = session.get('https://crob.at/api/me')
data = response.json()
print(data['user'])

Response:

{
  "user": {
    "username": "exampleuser"
  }
}

POST /api/showdown/assertion

Exchange the logged-in user's stored Showdown OAuth token for a challstr-specific assertion. Requires an authenticated crob.at session.

Request:

{
  "challstr": "12345|abcdefghijklmnopqrstuvwxyz"
}

Example:

curl -X POST https://crob.at/api/showdown/assertion \
  -H "Content-Type: application/json" \
  -H "Cookie: session=your-session-cookie" \
  -d '{"challstr":"12345|abcdefghijklmnopqrstuvwxyz"}'
const response = await fetch('https://crob.at/api/showdown/assertion', {
  method: 'POST',
  credentials: 'include',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    challstr: '12345|abcdefghijklmnopqrstuvwxyz'
  })
});

const data = await response.json();
console.log(data.assertion);
import requests

session = requests.Session()
session.cookies.set('session', 'your-session-cookie')

response = session.post(
    'https://crob.at/api/showdown/assertion',
    json={'challstr': '12345|abcdefghijklmnopqrstuvwxyz'},
)

data = response.json()
print(data['assertion'])

Response:

{
  "username": "exampleuser",
  "assertion": "..."
}

Notes