{"openapi":"3.1.0","info":{"title":"Ruby Social (BYOK) API","version":"0.1.0","description":"Ruby Social (BYOK) lets an AI assistant read your own Ruby Social data through the Ruby Social API with a key you supply (access token). Read-only: 12 tools (verify_credentials, get_account, lookup_account, list_account_posts, public_timeline, hashtag_timeline, home_timeline, trending_tags, trending_posts, search_accounts, search_posts, list_notifications). The BYOK key travels with each request,...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-ruby-social.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-ruby-social/docs"},"termsOfService":"https://connectorbay.com/byok-ruby-social/terms"},"servers":[{"url":"https://byok-ruby-social.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-ruby-social/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/verify_credentials":{"post":{"operationId":"verify_credentials","summary":"Show the ruby.social account the token belongs to: handle, display name, bio, follower and post counts. Use for \"Which r","description":"Show the ruby.social account the token belongs to: handle, display name, bio, follower and post counts. Use for \"Which ruby.social account is my token connected to\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"verify_credentialsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_account":{"post":{"operationId":"get_account","summary":"Get one account's public profile by its ID: handle, bio, bot flag, follower, following and post counts, last post date. ","description":"Get one account's public profile by its ID: handle, bio, bot flag, follower, following and post counts, last post date. Use for \"How many followers does ruby.social account 1 have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"id":{"description":"Account ID on ruby.social (an opaque string such as '1'), found in the id field of account results.","maxLength":200,"title":"Id","type":"string"}},"required":["id"],"title":"get_accountArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/lookup_account":{"post":{"operationId":"lookup_account","summary":"Find an account by handle (for example 'Gargron' for a local user) and return its ID and profile counts. Use for \"What i","description":"Find an account by handle (for example 'Gargron' for a local user) and return its ID and profile counts. Use for \"What is the account ID of Gargron on ruby.social\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"acct":{"description":"Handle to look up: 'username' for local accounts or 'username@domain' for remote ones.","maxLength":200,"title":"Acct","type":"string"}},"required":["acct"],"title":"lookup_accountArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_account_posts":{"post":{"operationId":"list_account_posts","summary":"List an account's posts, newest first, with text (HTML), date, counts and tags. Can skip replies and boosts. Use for \"Wh","description":"List an account's posts, newest first, with text (HTML), date, counts and tags. Can skip replies and boosts. Use for \"What has ruby.social account 1 posted recently\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"id":{"description":"Account ID on ruby.social (an opaque string such as '1'), found in the id field of account results.","maxLength":200,"title":"Id","type":"string"},"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"max_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return only results older than this ID (cursor for the next page).","title":"Max Id"},"min_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return results immediately newer than this ID (paginate forward).","title":"Min Id"},"only_media":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to keep only posts with attachments.","title":"Only Media"},"exclude_replies":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to leave out replies to other accounts.","title":"Exclude Replies"},"exclude_reblogs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to leave out boosts.","title":"Exclude Reblogs"},"tagged":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only posts that use this hashtag (without the # sign).","title":"Tagged"}},"required":["id"],"title":"list_account_postsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/public_timeline":{"post":{"operationId":"public_timeline","summary":"List recent public posts on ruby.social (local and federated), newest first, optionally only local, remote or with media","description":"List recent public posts on ruby.social (local and federated), newest first, optionally only local, remote or with media. Use for \"What is being posted publicly on ruby.social right now\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"max_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return only results older than this ID (cursor for the next page).","title":"Max Id"},"min_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return results immediately newer than this ID (paginate forward).","title":"Min Id"},"local":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to show only posts from this server.","title":"Local"},"remote":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to show only posts from other servers.","title":"Remote"},"only_media":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to keep only posts with attachments.","title":"Only Media"}},"title":"public_timelineArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/hashtag_timeline":{"post":{"operationId":"hashtag_timeline","summary":"List recent public posts that use one hashtag, newest first. Use for \"Show recent posts tagged #opensource on ruby.socia","description":"List recent public posts that use one hashtag, newest first. Use for \"Show recent posts tagged #opensource on ruby.social\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"hashtag":{"description":"Hashtag without the # sign, for example 'opensource'.","maxLength":200,"title":"Hashtag","type":"string"},"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"max_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return only results older than this ID (cursor for the next page).","title":"Max Id"},"min_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return results immediately newer than this ID (paginate forward).","title":"Min Id"},"local":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to show only posts from this server.","title":"Local"},"only_media":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to keep only posts with attachments.","title":"Only Media"}},"required":["hashtag"],"title":"hashtag_timelineArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/home_timeline":{"post":{"operationId":"home_timeline","summary":"List the latest posts from the accounts you follow, newest first (needs the read:statuses scope). Use for \"What is new o","description":"List the latest posts from the accounts you follow, newest first (needs the read:statuses scope). Use for \"What is new on my Mastodon home timeline\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"max_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return only results older than this ID (cursor for the next page).","title":"Max Id"},"min_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return results immediately newer than this ID (paginate forward).","title":"Min Id"}},"title":"home_timelineArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/trending_tags":{"post":{"operationId":"trending_tags","summary":"List hashtags that were used more than usual over the past week, with daily use and account counts. Use for \"Which hasht","description":"List hashtags that were used more than usual over the past week, with daily use and account counts. Use for \"Which hashtags are trending on ruby.social\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":20,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many tags to return (1 to 20).","title":"Limit"},"offset":{"anyOf":[{"maximum":1000,"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Skip this many results (for paging).","title":"Offset"}},"title":"trending_tagsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/trending_posts":{"post":{"operationId":"trending_posts","summary":"List posts that are getting more interaction than others right now, with counts and author. Use for \"What posts are tren","description":"List posts that are getting more interaction than others right now, with counts and author. Use for \"What posts are trending on ruby.social\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"offset":{"anyOf":[{"maximum":1000,"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Skip this many results (for paging).","title":"Offset"}},"title":"trending_postsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/search_accounts":{"post":{"operationId":"search_accounts","summary":"Search accounts on ruby.social by name or handle and return matching profiles. Use for \"Find accounts called 'nasa' on M","description":"Search accounts on ruby.social by name or handle and return matching profiles. Use for \"Find accounts called 'nasa' on Mastodon\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"q":{"description":"Search text: a name, handle or part of one.","maxLength":200,"title":"Q","type":"string"},"type":{"anyOf":[{"const":"accounts","type":"string"},{"type":"null"}],"default":"accounts","description":"Kind of result; fixed to accounts for this tool.","title":"Type"},"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"following":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to search only accounts you follow.","title":"Following"}},"required":["q"],"title":"search_accountsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/search_posts":{"post":{"operationId":"search_posts","summary":"Full-text search of posts on ruby.social (needs a token; results depend on the server's search setup). Use for \"Search M","description":"Full-text search of posts on ruby.social (needs a token; results depend on the server's search setup). Use for \"Search Mastodon posts about solar power\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"q":{"description":"Search text.","maxLength":200,"title":"Q","type":"string"},"type":{"anyOf":[{"const":"statuses","type":"string"},{"type":"null"}],"default":"statuses","description":"Kind of result; fixed to statuses for this tool.","title":"Type"},"limit":{"anyOf":[{"maximum":40,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 40).","title":"Limit"},"account_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only posts written by this account ID.","title":"Account Id"}},"required":["q"],"title":"search_postsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_notifications":{"post":{"operationId":"list_notifications","summary":"List your notifications (mentions, boosts, favourites, follows) newest first (needs the read:notifications scope). Use f","description":"List your notifications (mentions, boosts, favourites, follows) newest first (needs the read:notifications scope). Use for \"What notifications do I have on Mastodon\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":80,"minimum":1,"type":"integer"},{"type":"null"}],"default":40,"description":"How many notifications to return (1 to 80).","title":"Limit"},"max_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return only results older than this ID (cursor for the next page).","title":"Max Id"},"min_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Return results immediately newer than this ID (paginate forward).","title":"Min Id"}},"title":"list_notificationsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}