{
  "openapi": "3.1.0",
  "info": {
    "title": "Community Archive API",
    "version": "1.0.0",
    "summary": "Read the Community Archive tweet corpus with a personal API key.",
    "description": "Read-only access to the Community Archive corpus: tweets, accounts, archive members, text search, and archive likes and follows.\n\n**Authentication.** Every data endpoint needs an API key. Sign in at https://www.community-archive.org/settings/api-keys, create a key, and send it as `Authorization: Bearer cak_...`. Keep keys on servers and in scripts; never ship one in browser or app code. Revoked keys stop working within two minutes.\n\n**Limits.** Each key has a per-minute limit (default 60) and a UTC-day quota (default 20,000), and an account may have two requests running at once. Every response carries `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset`; a `429` carries `Retry-After`. Shared capacity is also bounded, so a `503` with `Retry-After` means retry shortly.\n\n**Data conventions.** IDs are strings. Timestamps are ISO 8601 UTC. Each tweet is its latest stored version; deleted or withdrawn tweets are omitted, so a page can hold fewer items than `limit`. Keep paging while `next_cursor` is not null, passing it back unchanged.\n\n**Replacing the Supabase REST API.** The public Supabase PostgREST corpus API (`fabxmporizzqflnftavs.supabase.co/rest/v1`) is being retired. See the migration guide: https://github.com/TheExGenesis/community-archive/blob/main/docs/api-v1-migration.md",
    "contact": {
      "name": "Community Archive",
      "url": "https://www.community-archive.org/docs"
    }
  },
  "servers": [
    {
      "url": "https://analytics.community-archive.org/v1"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Tweets"
    },
    {
      "name": "Accounts"
    },
    {
      "name": "Members"
    },
    {
      "name": "Social graph"
    },
    {
      "name": "Keys"
    }
  ],
  "paths": {
    "/tweets/{tweet_id}": {
      "get": {
        "tags": [
          "Tweets"
        ],
        "operationId": "getTweet",
        "summary": "Get one tweet",
        "parameters": [
          {
            "name": "tweet_id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tweet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TweetResponse"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/tweets": {
      "get": {
        "tags": [
          "Tweets"
        ],
        "operationId": "listTweets",
        "summary": "Look up tweets by ID, or list every tweet in a time window",
        "description": "Pass `ids` to look up up to 100 tweets (missing or withdrawn IDs are omitted; order follows `ids`). Or pass `since` and `until` (at most 31 days apart) to page through all tweets created in that window, ordered by tweet ID, which is chronological.",
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "description": "Comma-separated tweet IDs, at most 100.",
            "schema": {
              "type": "string",
              "example": "1883976555686420844,2111140591820267599"
            }
          },
          {
            "$ref": "#/components/parameters/Since"
          },
          {
            "$ref": "#/components/parameters/Until"
          },
          {
            "$ref": "#/components/parameters/Order"
          },
          {
            "$ref": "#/components/parameters/TweetLimit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Tweets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TweetPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/tweets/search": {
      "get": {
        "tags": [
          "Tweets"
        ],
        "operationId": "searchTweets",
        "summary": "Full-text search",
        "description": "Matches tweets containing every searchable word in `q` (or the exact phrase with `mode=phrase`). Page with `offset` up to 5,000; add `since`/`until` or `from_user` for faster, narrower searches.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 240
            }
          },
          {
            "name": "mode",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "phrase"
              ],
              "default": "all"
            }
          },
          {
            "name": "from_user",
            "in": "query",
            "description": "Author username.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reply_to_user",
            "in": "query",
            "description": "Only replies to this username.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "Inclusive date, YYYY-MM-DD.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "until",
            "in": "query",
            "description": "Inclusive date, YYYY-MM-DD.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "oldest",
                "likes",
                "reposts"
              ],
              "default": "newest"
            }
          },
          {
            "name": "exclude_retweets",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 5000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching tweets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/accounts/{account}": {
      "get": {
        "tags": [
          "Accounts"
        ],
        "operationId": "getAccount",
        "summary": "Get an account and its profile",
        "parameters": [
          {
            "$ref": "#/components/parameters/Account"
          }
        ],
        "responses": {
          "200": {
            "description": "The account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountResponse"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/accounts": {
      "get": {
        "tags": [
          "Accounts"
        ],
        "operationId": "listAccounts",
        "summary": "Look up accounts by ID or username",
        "description": "Provide exactly one of `ids` or `usernames` (at most 100). Unknown accounts are omitted.",
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "12,1150439796789190656"
            }
          },
          {
            "name": "usernames",
            "in": "query",
            "description": "Comma-separated, case-insensitive.",
            "schema": {
              "type": "string",
              "example": "jack,jondotbo"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Accounts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "request_id"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Account"
                      }
                    },
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/accounts/{account}/tweets": {
      "get": {
        "tags": [
          "Tweets",
          "Accounts"
        ],
        "operationId": "listAccountTweets",
        "summary": "Page through an account's tweets",
        "description": "Ordered by tweet ID (chronological), newest first by default. Use `order=asc` to read an account from its first tweet.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Account"
          },
          {
            "$ref": "#/components/parameters/Order"
          },
          {
            "$ref": "#/components/parameters/TweetLimit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Since"
          },
          {
            "$ref": "#/components/parameters/Until"
          },
          {
            "name": "exclude_replies",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "exclude_retweets",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tweets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TweetPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/members": {
      "get": {
        "tags": [
          "Members"
        ],
        "operationId": "listMembers",
        "summary": "List archive members",
        "description": "Accounts that uploaded an archive or opted in, ordered by account ID. Opted-out accounts are never listed.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 1000
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Members.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "next_cursor",
                    "request_id"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Member"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/accounts/{account}/likes": {
      "get": {
        "tags": [
          "Social graph"
        ],
        "operationId": "listAccountLikes",
        "summary": "Tweets an archive member liked",
        "description": "From the member's uploaded archive, newest liked tweet ID first. Only accounts that uploaded an archive have likes.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Account"
          },
          {
            "$ref": "#/components/parameters/SocialLimit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "One page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LikePage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/accounts/{account}/followers": {
      "get": {
        "tags": [
          "Social graph"
        ],
        "operationId": "listAccountFollowers",
        "summary": "An archive member's followers",
        "description": "From the member's uploaded archive, ordered by account ID.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Account"
          },
          {
            "$ref": "#/components/parameters/SocialLimit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "One page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RelatedAccountPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/accounts/{account}/following": {
      "get": {
        "tags": [
          "Social graph"
        ],
        "operationId": "listAccountFollowing",
        "summary": "Accounts an archive member follows",
        "description": "From the member's uploaded archive, ordered by account ID.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Account"
          },
          {
            "$ref": "#/components/parameters/SocialLimit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "One page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RelatedAccountPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/me": {
      "get": {
        "tags": [
          "Keys"
        ],
        "operationId": "getCurrentKey",
        "summary": "Check a key and its limits",
        "responses": {
          "200": {
            "description": "The calling key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "request_id"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KeyInfo"
                    },
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "Keys"
        ],
        "operationId": "getOpenApi",
        "summary": "This document",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "cak_<key id>_<secret>",
        "description": "Create a key at https://www.community-archive.org/settings/api-keys."
      }
    },
    "parameters": {
      "Account": {
        "name": "account",
        "in": "path",
        "required": true,
        "description": "Numeric account ID, or username. Prefix a numeric username with `@`.",
        "schema": {
          "type": "string",
          "example": "jack"
        }
      },
      "Since": {
        "name": "since",
        "in": "query",
        "description": "Inclusive start: YYYY-MM-DD (UTC midnight) or an ISO 8601 timestamp with a zone.",
        "schema": {
          "type": "string",
          "example": "2026-10-01"
        }
      },
      "Until": {
        "name": "until",
        "in": "query",
        "description": "Exclusive end: YYYY-MM-DD (UTC midnight) or an ISO 8601 timestamp with a zone.",
        "schema": {
          "type": "string",
          "example": "2026-10-02T00:00:00Z"
        }
      },
      "Order": {
        "name": "order",
        "in": "query",
        "schema": {
          "type": "string",
          "enum": [
            "desc",
            "asc"
          ],
          "default": "desc"
        }
      },
      "TweetLimit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 100
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "`next_cursor` from the previous page. Opaque; pass it back unchanged.",
        "schema": {
          "type": "string"
        }
      },
      "SocialLimit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500,
          "default": 100
        }
      }
    },
    "schemas": {
      "Id": {
        "type": "string",
        "pattern": "^[0-9]{1,20}$"
      },
      "Timestamp": {
        "type": "string",
        "format": "date-time",
        "example": "2026-10-16T17:01:54.000Z"
      },
      "Media": {
        "type": "object",
        "required": [
          "media_id",
          "media_url",
          "media_type",
          "width",
          "height"
        ],
        "properties": {
          "media_id": {
            "$ref": "#/components/schemas/Id"
          },
          "media_url": {
            "type": "string"
          },
          "media_type": {
            "type": "string",
            "example": "photo"
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "Url": {
        "type": "object",
        "required": [
          "url",
          "expanded_url",
          "display_url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "expanded_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_url": {
            "type": "string"
          }
        }
      },
      "Tweet": {
        "type": "object",
        "required": [
          "tweet_id",
          "account_id",
          "username",
          "account_display_name",
          "avatar_media_url",
          "created_at",
          "full_text",
          "favorite_count",
          "retweet_count",
          "reply_to_tweet_id",
          "reply_to_user_id",
          "reply_to_username",
          "quoted_tweet_id",
          "retweeted_tweet_id",
          "conversation_id",
          "media",
          "urls",
          "mentioned_account_ids"
        ],
        "properties": {
          "tweet_id": {
            "$ref": "#/components/schemas/Id"
          },
          "account_id": {
            "$ref": "#/components/schemas/Id"
          },
          "username": {
            "type": [
              "string",
              "null"
            ],
            "description": "Author's current username."
          },
          "account_display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_media_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "full_text": {
            "type": "string"
          },
          "favorite_count": {
            "type": "integer"
          },
          "retweet_count": {
            "type": "integer"
          },
          "reply_to_tweet_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "reply_to_user_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "reply_to_username": {
            "type": [
              "string",
              "null"
            ]
          },
          "quoted_tweet_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "retweeted_tweet_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "conversation_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            }
          },
          "urls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Url"
            }
          },
          "mentioned_account_ids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Id"
            }
          }
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "account_id",
          "username",
          "account_display_name",
          "account_created_at",
          "bio",
          "website",
          "location",
          "avatar_media_url",
          "header_media_url",
          "num_tweets",
          "num_followers",
          "num_following",
          "num_likes",
          "is_member",
          "has_archive",
          "is_opted_in",
          "latest_observed_at"
        ],
        "properties": {
          "account_id": {
            "$ref": "#/components/schemas/Id"
          },
          "username": {
            "type": "string"
          },
          "account_display_name": {
            "type": "string"
          },
          "account_created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "bio": {
            "type": [
              "string",
              "null"
            ]
          },
          "website": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_media_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "header_media_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "num_tweets": {
            "type": [
              "integer",
              "null"
            ]
          },
          "num_followers": {
            "type": [
              "integer",
              "null"
            ]
          },
          "num_following": {
            "type": [
              "integer",
              "null"
            ]
          },
          "num_likes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "is_member": {
            "type": "boolean",
            "description": "Uploaded an archive or opted in."
          },
          "has_archive": {
            "type": "boolean"
          },
          "is_opted_in": {
            "type": "boolean"
          },
          "latest_observed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When these profile fields were last observed."
          }
        }
      },
      "Member": {
        "type": "object",
        "required": [
          "account_id",
          "username",
          "account_display_name",
          "avatar_media_url",
          "has_archive",
          "is_opted_in",
          "joined_at"
        ],
        "properties": {
          "account_id": {
            "$ref": "#/components/schemas/Id"
          },
          "username": {
            "type": "string"
          },
          "account_display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_media_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "has_archive": {
            "type": "boolean"
          },
          "is_opted_in": {
            "type": "boolean"
          },
          "joined_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "KeyInfo": {
        "type": "object",
        "required": [
          "key_id",
          "consumer_id",
          "scopes",
          "requests_per_minute",
          "requests_per_day",
          "expires_at"
        ],
        "properties": {
          "key_id": {
            "type": "string"
          },
          "consumer_id": {
            "type": "string",
            "format": "uuid"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "requests_per_minute": {
            "type": "integer"
          },
          "requests_per_day": {
            "type": "integer"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "TweetResponse": {
        "type": "object",
        "required": [
          "data",
          "request_id"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Tweet"
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "AccountResponse": {
        "type": "object",
        "required": [
          "data",
          "request_id"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Account"
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "TweetPage": {
        "type": "object",
        "required": [
          "data",
          "request_id"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tweet"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Present for paged listings; null on the last page."
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "SearchPage": {
        "type": "object",
        "required": [
          "data",
          "next_offset",
          "request_id"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tweet"
            }
          },
          "next_offset": {
            "type": [
              "integer",
              "null"
            ]
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "request_id"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "unauthorized",
                  "forbidden",
                  "not_found",
                  "method_not_allowed",
                  "rate_limited",
                  "too_many_failed_authentications",
                  "too_many_concurrent_requests",
                  "client_closed_request",
                  "busy",
                  "query_budget_exceeded",
                  "timeout",
                  "auth_unavailable",
                  "not_configured",
                  "stale_projection",
                  "upstream_unavailable"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "Like": {
        "type": "object",
        "required": [
          "liked_tweet_id",
          "full_text",
          "author_account_id"
        ],
        "properties": {
          "liked_tweet_id": {
            "$ref": "#/components/schemas/Id"
          },
          "full_text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Text of the liked tweet as captured in the archive; null unless that copy is live and attributed. Look up the tweet itself with /tweets?ids= for current text and media."
          },
          "author_account_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "RelatedAccount": {
        "type": "object",
        "required": [
          "account_id",
          "username",
          "account_display_name",
          "avatar_media_url"
        ],
        "properties": {
          "account_id": {
            "$ref": "#/components/schemas/Id"
          },
          "username": {
            "type": [
              "string",
              "null"
            ]
          },
          "account_display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_media_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "LikePage": {
        "type": "object",
        "required": [
          "data",
          "total",
          "next_cursor",
          "request_id"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Like"
            }
          },
          "total": {
            "type": "integer",
            "description": "Exact number of edges for this account."
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "RelatedAccountPage": {
        "type": "object",
        "required": [
          "data",
          "total",
          "next_cursor",
          "request_id"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedAccount"
            }
          },
          "total": {
            "type": "integer",
            "description": "Exact number of edges for this account."
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "request_id": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid parameters.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not found, or withdrawn from the archive.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error": {
        "description": "401 missing or invalid key; 403 key lacks the scope; 422 the query exceeded its resource budget (narrow it); 429 rate limited or more than two requests in flight for your account (see Retry-After); 503 busy or temporarily unavailable (see Retry-After); 504 timeout.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
