Skip to content

docs: add the X Calls API (preview, don't merge yet) - #479

Open
santiagomed wants to merge 3 commits into
mainfrom
smedina/x-calls-api
Open

santiagomed wants to merge 3 commits into
mainfrom
smedina/x-calls-api

Conversation

@santiagomed

Copy link
Copy Markdown
Collaborator

Adds a Calls API product for the X Calls developer API, which is in development. Don't merge yet: merging publishes these pages on docs.x.com before the API is available. This PR is here for the Mintlify preview.

Pages

  • Start here: introduction, quickstart, authentication.
  • Guides: media WebSocket, calling people, scheduled calls, example agent, errors and limits.
  • API reference for all 10 endpoints (/2/calls, /2/calls/:id, join, leave, and /2/calls/scheduled list, schedule, get, update, cancel, rsvp), rendered from xcalls/openapi.json.

xcalls/openapi.json is generated from the X API route registry's development version, so it matches what the platform serves. The guides follow the calls-api developer guide in the xai repo.

Checks

  • mint broken-links: no broken links.
  • Every new page compiles as MDX, and every reference page resolves to its operation in xcalls/openapi.json with Mintlify's own resolver; the spec passes Mintlify's OpenAPI validation.
A Calls API product: introduction, quickstart, authentication, the media
WebSocket, calling people, scheduled calls, an example agent, errors and
limits, and an API reference rendered from xcalls/openapi.json (generated
from the X API route registry's development version).
@mintlify

mintlify Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
x-corp 🟢 Ready View Preview Oct 6, 2026, 12:04 AM
X Calls launches without linked Google or Outlook calendars: the list
returns X Calls events only, and scheduled calls have no calendar field.
GET /2/calls/scheduled lists events on linked Outlook calendars that meet in
an X call (calendar: "outlook", no id) next to X Calls events (calendar: "x").
brettdavies added a commit to brettdavies/xurl-rs that referenced this pull request Oct 26, 2026
…r calls a preview (#366)

## Summary

Vendors the 2026-10-24 upstream content of X API 2.172. X changed the
spec without bumping `info.version`; the new content adds five
operations and 17 schemas:

- `POST /2/calls`, `POST /2/calls/{id}/join`, and `POST
/2/calls/{id}/leave`: start a live call, join it, and leave it.
- `GET /2/users/me/followers` and `GET /2/users/me/following`: the
caller's own followers and following, without the caller's id in the
path.

`cargo build` regenerates the auth matrix with the five operations. No
endpoint behind a shortcut was renamed or removed,
`spec_types_validation` passes, and nothing retires. No command is added
for the five operations; the decision and the open question are under
Additional Context. All five are reachable in raw mode.

**`xr calls` is labeled a preview.** X marks the Calls API as in
development and not yet generally available, and its preview
documentation names different OAuth2 scopes (`dm.read`, `dm.write`) from
the vendored spec (`calls.read`, `calls.write`). `xr --help`, `xr calls
--help`, the completions, and `crates/xurl-cli/README.md` now say so,
and the README explains why starting, joining, and leaving a live call
have no command.

## Changelog (xurl-rs)

### Changed

- Change the vendored X API spec to the 2026-10-24 upstream content of
2.172, which adds starting, joining, and leaving a live call and the
caller's own followers and following lists. All five are reachable in
raw mode; shortcut behavior is unchanged.

### Documentation

- Label `xr calls` a preview in its help and the README: X marks the
Calls API as in development and not yet generally available, so its
requests and the scopes it takes can change.

## Changelog (xdk-rs)

### Changed

- Change the vendored X API spec to the 2026-10-24 upstream content of
2.172, which adds `POST /2/calls`, `POST /2/calls/{id}/join`, `POST
/2/calls/{id}/leave`, `GET /2/users/me/followers`, and `GET
/2/users/me/following` with their schemas. `API_SPEC_SHA256` and
`API_SPEC_DATE` follow, and the auth matrix gains the five operations;
no typed response or shortcut changes.

## Type of Change

- [x] `feat`: New feature (non-breaking change which adds functionality)
- [ ] `fix`: Bug fix (non-breaking change which fixes an issue)
- [ ] `refactor`: Code refactoring (no functional changes)
- [ ] `perf`: Performance improvement
- [x] `docs`: Documentation update
- [ ] `test`: Adding or updating tests
- [ ] `chore`: Maintenance tasks (dependencies, config, etc.)
- [ ] `ci`: CI/CD configuration changes
- [ ] `style`: Code style/formatting changes
- [ ] `build`: Build system changes
- [ ] `BREAKING CHANGE`: Breaking API change (requires major version
bump)

## Related Issues/Stories

- Story: n/a
- Issue: n/a
- Architecture: AGENTS.md § "Spec-refresh PRs" and § "Command grammar:
flags vs subcommands"
- Related PRs: #340 vendored the first 2.172 content and built `xr
calls` and `xr broadcasts sources`. #341 and this PR both regenerate the
same completions and `help.golden` lines, so this carries #341's
`bookmark-folders` lines beside its own `calls` label. #370 records the
live-call decision below, and the `/me` lists decision, in
`endpoint-decisions.json`.

## Testing

- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [x] Manual testing completed
- [x] All tests passing

**Test Summary:**

- The regenerated auth matrix covers every declared endpoint
(`auth_matrix_coverage`), and every typed response still matches its
schema in the new spec (`spec_types_validation`).
- `help.golden` and `help-calls.golden` move for the preview label; no
other fixture moves.

## Files Modified

**Modified:**

- `crates/xdk/vendor/x-api-openapi.json`,
`crates/xdk/vendor/spec-metadata.json`, `crates/xdk/vendor/README.md`:
the vendored spec.
- `crates/xurl-cli/src/cli/mod.rs`: the `calls` family's help says it is
a preview.
- `crates/xurl-cli/README.md`: the preview paragraph.
- `crates/xurl-cli/tests/golden/help.golden`,
`crates/xurl-cli/tests/golden/help-calls.golden`;
`completions/xr.{elvish,fish,powershell,zsh}`.

**Created:**

- None.

**Renamed:**

- None.

**Deleted:**

- None.

## Breaking Changes

- [x] No breaking changes
- [ ] Breaking changes described below:

## Deployment Notes

- [x] No special deployment steps required
- [ ] Deployment steps documented below:

## Checklist

- [x] Code follows project conventions and style guidelines
- [x] Commit messages follow [Conventional
Commits](https://www.conventionalcommits.org/)
- [x] Self-review of code completed
- [x] Tests added/updated and passing
- [x] No new warnings or errors introduced
- [x] Changes are backward compatible (or breaking changes documented)

## Additional Context

### Decided

- **Starting, joining, and leaving a live call get no command** (decided
2026-10-26). Joining returns a single-use `media_token`, valid about two
minutes, for a WebSocket (`wss://api.x.com/2/calls/media`) that carries
the call as real-time PCM16 audio in 20 ms frames plus JSON events and
commands; the caller enters the call only while that socket is open.
`xr` does not drive it, so `xr calls join` would hand out a token the
caller still needs a media client to use, and starting a call makes an
empty call that `xr calls scheduled add` already provides with a
shareable link. Revisit when X makes the Calls API generally available
and a real audio bridge (`xr calls join ... -- <program>`) is planned.
The media protocol is documented in X's unmerged preview docs,
xdevplatform/docs#479. #370 records this as the `calls-live` entry in
`endpoint-decisions.json`, which reopens when that docs PR merges.

- **`GET /2/users/me/followers` and `GET /2/users/me/following` get no
command of their own; `xr followers` and `xr following` use them**
(decided 2026-10-26, recorded as `me-follow-lists` in #370, planned).
Without `--of`, the two commands will call `/2/users/me/...` and skip
the account-id lookup; with `--of` they keep `/2/users/{id}/...`.
AGENTS.md's command grammar gains a stated exception for the caller's
own variant when this is built. Nothing in this PR changes their
behavior.

### Open decisions

- None.

### Breaking changes

- None.
brettdavies added a commit to brettdavies/xurl-rs that referenced this pull request Oct 26, 2026
…#370)

## Summary

Records the endpoints `xr` deliberately leaves without a command, so a
sweep or the daily spec-drift run stops proposing one that was already
decided, and reports when the reason behind a decision changes.

**`endpoint-decisions.json`** records what was decided for every
operation in the vendored spec that has no shortcut command. Each entry
names its operations (`METHOD /path`, `*` for any method, a trailing
`/**` for a path and everything below it), a status, the reason, and who
decided and when. `raw-only` and `not-supported` mean no command until
`revisit_when` fires: `never`, `github-pr-merged` (repo, number), or
`crate-published` (crate). `planned` names a command family to build; it
takes no trigger, and its entry is removed when the command ships.

Of the spec's 241 operations, 69 have a shortcut (with #341's bookmark
folders) and the other 172 fall under 31 decisions. Brett made each
call, group by group, on 2026-10-26, except the three made earlier
(`xchat` on #340, `calls-live` on #366, `activity` on 2026-10-05).

**No command (11):**

| id | Covers | Status | Reopens when |
| -- | ------ | ------ | ------------ |
| `xchat` | `/2/chat/**` and the X Chat public keys (47) | not-supported
| `chat-xdk-core` is published on crates.io |
| `calls-live` | start, join, and leave a call (3) | not-supported |
xdevplatform/docs#479 merges, X's sign the Calls API is generally
available |
| `activity` | `/2/activity/**` (6) | raw-only | never |
| `streams` | the 14 declared streams | raw-only | never: `xr -s <path>`
streams them |
| `posts-full-archive` | full-archive search and counts (2) | raw-only |
never |
| `post-repost-objects` | `GET /2/tweets/{id}/retweets` | raw-only |
never |
| `users-minor-reads` | reposts of me, affiliates (2) | raw-only | never
|
| `dm-legacy-media` | legacy DM media download | raw-only | never |
| `spaces-ticket-buyers` | `GET /2/spaces/{id}/buyers` | raw-only |
never |
| `app-administration` | bots, compliance jobs, streaming connections,
developer account (18) | raw-only | never |
| `openapi-document` | `GET /2/openapi.json` | raw-only | never |

**Planned command families (20):** `lists` (17 operations),
`dm-conversations` (8), `broadcasts` (scheduled broadcasts, chat, your
broadcasts; 13), `community-notes` (5), `spaces` (5), `post-engagement`
(likers, reposters, quotes; 3), `users-lookup` (3), `stream-rules` (3),
`media-lookup` (3), `me-follow-lists` (2: `xr followers` and `xr
following` without `--of` call `/2/users/me/...`), `trends` (2), `news`
(2), `communities` (2), `articles` (2), and one operation each for
`posts-lookup`, `post-counts`, `hidden-replies`, `post-analytics`,
`users-search`, and `user-posts`. Each entry's reason says what the
command does.

**`crates/xdk/tests/endpoint_decisions.rs`** holds the file offline. It
fails for a spec operation with neither a shortcut nor a decision, for
an entry naming an operation the spec lacks, for a decision covering an
endpoint that has a shortcut (so a planned entry is removed when its
command ships), for an operation under two decisions, and for an entry
missing its id, reason, date, decider, or a trigger its status requires.

**`scripts/endpoint-decisions.sh`** has two verbs. `covered OLD NEW`
lists the operations a spec refresh adds that a decision covers, and
what to do: build a planned one, leave the others. `triggers` prints
each decision as `fired`, `holding`, `planned`, or `unknown`, reading
GitHub with `gh` and crates.io over HTTPS.

**The spec-drift workflow** uses both. Every scheduled run writes the
trigger report to its summary and raises a warning for a fired one,
including a run that finds no drift. A refresh PR's runbook gains an
Endpoint decisions section. Step 4 now says what a refresh does: build
support for each added endpoint no decision rules out, and propose a
decision for one to leave without a command. "Do not create shortcuts
for added endpoints" no longer matches how refresh PRs are reconciled
(#340, #366). Because the test requires every operation to be covered, a
refresh that adds an endpoint stays red until the endpoint is built, or
until a person decides it.

## Changelog (xurl-rs)

## Changelog (xdk-rs)

## Type of Change

- [ ] `feat`: New feature (non-breaking change which adds functionality)
- [ ] `fix`: Bug fix (non-breaking change which fixes an issue)
- [ ] `refactor`: Code refactoring (no functional changes)
- [ ] `perf`: Performance improvement
- [ ] `docs`: Documentation update
- [x] `test`: Adding or updating tests
- [ ] `chore`: Maintenance tasks (dependencies, config, etc.)
- [x] `ci`: CI/CD configuration changes
- [ ] `style`: Code style/formatting changes
- [ ] `build`: Build system changes
- [ ] `BREAKING CHANGE`: Breaking API change (requires major version
bump)

## Related Issues/Stories

- Story: n/a
- Issue: n/a
- Architecture: AGENTS.md § "Spec-refresh PRs"
- Related PRs: it needs #366's vendored spec, which carries the
`calls-live` and `me-follow-lists` operations, and #341's
bookmark-folder shortcuts, which the coverage test counts.

## Testing

- [x] Unit tests added/updated
- [ ] Integration tests added/updated
- [x] Manual testing completed
- [x] All tests passing

**Test Summary:**

- `endpoint_decisions.rs`: six tests. A planted stale operation, a
planted operation with a shortcut, and a removed entry (`articles`) each
fail their test with the decision and the operations named.
- `scripts/endpoint-decisions.sh covered` against `dev`'s spec and this
branch's lists the three `calls-live` operations; against itself it
reports no addition. `triggers` reports all three decisions holding;
pointed at a published crate and a merged pull request, it reports both
fired.
- `actionlint` and `shellcheck` pass on the workflow and the script.

## Files Modified

**Modified:**

- `.github/workflows/spec-drift.yml`: the daily trigger report, the
runbook's Endpoint decisions section, and step 4 and the
decision-authority lines.
- `AGENTS.md` § "Spec-refresh PRs": the file, its trigger kinds, and the
test that holds it.

**Created:**

- `endpoint-decisions.json`
- `crates/xdk/tests/endpoint_decisions.rs`
- `scripts/endpoint-decisions.sh`

**Renamed:**

- None.

**Deleted:**

- None.

## Breaking Changes

- [x] No breaking changes
- [ ] Breaking changes described below:

## Deployment Notes

- [x] No special deployment steps required
- [ ] Deployment steps documented below:

## Checklist

- [x] Code follows project conventions and style guidelines
- [x] Commit messages follow [Conventional
Commits](https://www.conventionalcommits.org/)
- [x] Self-review of code completed
- [x] Tests added/updated and passing
- [x] No new warnings or errors introduced
- [x] Changes are backward compatible (or breaking changes documented)

This branch was successfully deployed

1 active deployment
staging — b8b777f4 Deployed Oct 6, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant