Skip to main content
POST
/
orgs
/
{identifier}
/
matches
curl -X POST https://teambattles.gg/api/v1/orgs/Esports_Org/matches \
  -H "Authorization: Bearer tb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"leagueTeamsOnly": true, "excludeStatuses": ["CANCELLED"], "numItems": 50}'
{
  "page": [
    {
      "id": "<string>",
      "game": {
        "id": "<string>",
        "nameKey": "<string>"
      },
      "gameMode": "<string>",
      "creatorTeam": {
        "id": "<string>",
        "name": "<string>",
        "tag": "<string>",
        "avatarUrl": "<string>"
      },
      "acceptedTeam": {
        "id": "<string>",
        "name": "<string>",
        "tag": "<string>",
        "avatarUrl": "<string>"
      },
      "scheduledAt": "<string>",
      "startedAt": "<string>",
      "completedAt": "<string>",
      "bestOf": 0
    }
  ],
  "isDone": true,
  "continueCursor": "<string>"
}
curl -X POST https://teambattles.gg/api/v1/orgs/Esports_Org/matches \
  -H "Authorization: Bearer tb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"leagueTeamsOnly": true, "excludeStatuses": ["CANCELLED"], "numItems": 50}'

Permission Required

This endpoint requires the matches.org_matches permission on your API key.

Membership Required

You must be an active member of the organization to access its matches. If you’re not a member, you’ll receive a 403 error with code error_org_membership_required.

Organization Identifier

The {identifier} path parameter accepts either:
  • Organization ID: The Convex document ID (e.g., kd8xyz789ghi012)
  • Organization Slug: The URL-friendly org name (e.g., Esports_Org)
The slug is derived from the organization name by replacing spaces with underscores.

What’s Returned

This endpoint returns matches for all teams within the organization. This is useful for organization admins or dashboards that need to see activity across all teams.

Filtering Options

League Teams Only

The leagueTeamsOnly parameter is unique to this endpoint:
ParameterTypeDescription
leagueTeamsOnlybooleanOnly include matches involving LEAGUE type teams
LEAGUE teams are teams created for organized league play, as opposed to regular competitive teams.

Status Filtering

Filter matches by their status:
  • includeStatuses: Only return matches with these statuses (takes precedence)
  • excludeStatuses: Return all matches except those with these statuses

Date Filtering

Filter by scheduled or creation dates using ISO 8601 format:
  • scheduledAfter / scheduledBefore: Filter by scheduled match time
  • createdAfter / createdBefore: Filter by when the match was created

Other Filters

  • gameId: Filter by a specific game
  • opponentId: Filter by opponent team (accepts team ID or slug)

Pagination

Results are paginated with a default of 25 matches per page (maximum 100).

Request Fields

ParameterTypeDescription
numItemsnumberNumber of items per page, 1-100, default 25
cursorstringOpaque cursor string from a prior response (optional)

Response Fields

FieldTypeDescription
pagearrayArray of matches for this page
isDonebooleantrue when there are no more pages to fetch
continueCursorstringPass back as cursor on the next request
Example response envelope:
{
	"page": [],
	"isDone": false,
	"continueCursor": "eyJpZCI6Im1hdGNoXzEyMyIsInRzIjoxNzA0MDY3MjAwfQ=="
}

Errors

CodeHTTP StatusWhen
error_api_key_required401Missing Authorization header
error_api_key_invalid401API key is unknown, revoked, or expired
error_api_key_permission_denied403The key does not hold matches.org_matches: read
error_org_membership_required403You are not an active member of the requested organization
error_invalid_num_items400numItems is outside the allowed 1-100 range
error_invalid_limit400Reserved for limit-style page sizes (registry-level error code)
error_invalid_cursor400cursor is malformed or no longer valid
error_invalid_date_format400One of the scheduled*/created* filters is not ISO 8601
error_org_not_found404The {identifier} could not be resolved to an organization
error_team_not_found404opponentId could not be resolved to a team
error_internal500Unhandled server error - retry or contact support

Common Use Cases

Get All League Matches

{
	"leagueTeamsOnly": true,
	"numItems": 50
}

Get Active Matches Across All Teams

{
	"excludeStatuses": ["PENDING", "COMPLETED", "CANCELLED", "FORFEITED"],
	"numItems": 50
}

Get Completed League Matches for Stats

{
	"leagueTeamsOnly": true,
	"includeStatuses": ["COMPLETED", "FORFEITED"],
	"numItems": 100
}

Get Matches for a Specific Game

{
	"gameId": "call_of_duty_bo7",
	"excludeStatuses": ["CANCELLED"]
}

Get Organization Match History for a Season

{
	"scheduledAfter": "2024-01-01T00:00:00Z",
	"scheduledBefore": "2024-06-30T23:59:59Z",
	"leagueTeamsOnly": true,
	"includeStatuses": ["COMPLETED"],
	"numItems": 100
}

Authorizations

Authorization
string
header
required

Send your API key as: Authorization: Bearer tb_

Path Parameters

identifier
string
required

Organization id or slug.

Body

application/json

Filters and cursor pagination for listing matches.

numItems
integer
default:25

Page size (1-100). Defaults to 25.

Required range: 1 <= x <= 100
cursor
string | null

Opaque continuation cursor from a prior page's continueCursor.

includeStatuses
string[]

Only include matches with these MatchStatus codes; unknown values are ignored.

excludeStatuses
string[]

Exclude matches with these MatchStatus codes; unknown values are ignored.

gameId
string

Filter to a single game by id.

scheduledAfter
string

ISO 8601; only matches scheduled at or after this time.

scheduledBefore
string

ISO 8601; only matches scheduled at or before this time.

createdAfter
string

ISO 8601; only matches created at or after this time.

createdBefore
string

ISO 8601; only matches created at or before this time.

opponentId
string

Filter to matches against this opponent team (team id or slug).

Response

Cursor-paginated result. continueCursor is non-null even when isDone is true.

page
object[]
required
isDone
boolean
required
continueCursor
string
required