Skip to Content
IntegrationsAPIOverview

API

DiscMeet exposes a small read-only HTTP API under /v1. You call it from your own scripts, backends, or ETL jobs using a server-specific API key (not your Discord login). Responses are JSON and include meeting metadata, notes, transcript text, and related fields for each listed recording.


BASE URL

https://api.discmeet.com/v1

Who can use it

  • The Discord server must have the DiscMeet bot installed and enabled.
  • Pro+ on the guild owner’s account is required to create or rotate an API key.
  • Anyone who can open Integrations  for that server (Administrator, Manage Server, or server owner) can generate or revoke the key from the dashboard.

Creating and storing an API key

Keys are created in the browser—there is no “sign up for API key” form outside the dashboard.

  1. Sign in at discmeet.com/dashboard .
  2. Select the Discord server.
  3. Open Integrations (or the API section within Integrations, depending on the UI layout).
  4. Use generate / rotate to create a token. Copy it once; the full secret is not shown again (you may see only a last-four hint afterward).
  5. Store it in a secret manager or environment variable on the system that calls the API—never commit it to git or send it in client-side browser code.

Sending the API key (authentication)

Authorization: Bearer <token>

Method & pathDescription
GET /v1/meetingsPaginated voice meeting transcripts (eligible rows only). Supports since, limit, page filters.
GET /v1/meetings/:idFetch a single voice meeting by its UUID.
GET /v1/sessionsPaginated RPG session transcripts. Supports since, limit, page, and campaign_id filters. Each row includes campaign_id + campaign_name.
GET /v1/sessions/:idFetch a single RPG session by its UUID. Same payload as a list row (includes campaign_id + campaign_name), wrapped under session.
GET /v1/campaignsList RPG campaigns in the server (id, name, description, active, session count). Used to resolve a user-facing campaign name to the numeric id needed by sessions?campaign_id=… and campaigns/:id. Supports `?active=true
GET /v1/campaigns/:idFetch one campaign plus its nested characters (players/NPCs), items, locations, and organizations — the entities you curate from the dashboard. One round-trip for the campaign’s full world bible.

All endpoints use the same auth header, plan gating, and rate limits. List responses share the same shape (different top-level key: meetings / sessions / campaigns); single-resource endpoints wrap their object under meeting, session, or campaign.


Pagination

List endpoints (/v1/meetings, /v1/sessions) accept these query params:

QueryMeaning
pageOptional. 1-based page index. Default 1. Must be a positive integer if present.
sinceOptional. ISO8601 cutoff (e.g. 2026-05-25T00:00:00Z). Returns only items that started at or after this time. Defaults to 30 days ago. Maximum lookback is 1 year. Currently only /v1/meetings accepts this param.
limitOptional. Override the default page size. Default 50, capped at 50. Currently only /v1/meetings accepts this param.

Each page contains up to limit items (default 50). The response includes a meta object:

FieldTypeMeaning
pageintegerCurrent page.
per_pageintegerPage size for this response (matches the limit you requested, or 50 if you didn’t pass one).
nextbooleanMore results exist after this page.
prevbooleanA previous page exists (page > 1).

When meta.next is true, request the next page with ?page=<current + 1> (and the same since / limit if you used them).


What appears in lists (eligibility)

Only ended meetings or ended RPG sessions are listed, and only if:

  • A transcription exists, and
  • Notes are non-empty (same practical rule as the dashboard transcript list: empty or cleared notes are skipped).

Only sessions whose started_at is within the last 30 days are included (aligned with the dashboard transcript window).


Rate limits

Two independent limits apply (both are 100 requests per 60 seconds):

  1. Per client IP — Enforced before your token is validated. Applies to any path under /v1.
  2. Per guild — After the token is resolved to a server.

On 429 Too Many Requests, the response may include:

  • Header Retry-After: suggested wait time in seconds.
  • Headers X-RateLimit-Limit and X-RateLimit-Window (guild limit path).

JSON body shape for rate limits:

{
  "error": "rate_limited",
  "message": "IP rate limit exceeded (100 requests per 60 seconds).",
  "scope": "ip"
}

scope is either "ip" or "guild".


Error responses

Errors use a small JSON envelope suitable for both humans and automation:

FieldMeaning
errorShort machine-readable code (string).
messageHuman-readable explanation.

Common HTTP status codes:

StatuserrorTypical cause
400bad_requestInvalid query (e.g. page not a positive integer).
401unauthorizedMissing/invalid Authorization Bearer token.
404not_foundReserved for future single-resource routes; not used for these list routes today.
429rate_limitedIP or guild throttle (see scope).
500internal_errorUnexpected server failure (generic message in production).

Examples:

{ "error": "unauthorized", "message": "Invalid or missing Bearer token." }
{
  "error": "rate_limited",
  "message": "Guild rate limit exceeded (100 requests per 60 seconds).",
  "scope": "guild"
}

Unknown paths under /v1 may still return an HTML 404 from the framework instead of JSON until handled at the edge.


Response object fields (list items)

Each object in meetings or sessions includes:

FieldMeaning
meeting_idPublic id for that recording (meeting or RPG session).
guild_discord_idDiscord server snowflake.
recording_type"meeting" or "session".
discord_channel_nameName of the transcript destination text channel when resolvable.
participant_namesArray of display names (speaking order / metadata).
notesSummary notes for the recording.
transcriptTimestamped speaker lines.
audio_urlHTTPS URL for the merged full-session MP3 (…/recordings/{meeting_id}/audio.mp3 on DiscMeet’s recording host). The file is only available after merged audio exists (requires MP3 recording enabled for the server); until then, fetching the URL may fail.
occurred_atISO 8601 timestamp (typically when notes were last updated, with fallbacks).

These JSON responses are not signed; treat HTTPS and your token handling as the trust boundary.


Example requests (by language)

Replace YOUR_TOKEN and adjust the path (meetings or sessions) as needed.

curl -sS \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.discmeet.com/v1/meetings?page=1"

LLM / integration notes

  • Intent: Fetch recent transcript rows for one Discord server using a static Bearer token.
  • Idempotency: GET only; safe to retry (respect 429 + Retry-After).
  • Correlation: Use meeting_id as the stable id for a recording when syncing or deduplicating.
  • Completeness: Lists are paginated and filtered (30-day window, non-empty notes). Do not assume a single page is the full history.
  • Secrets: Never log the full Authorization header.

Next

Last updated on