{"openapi":"3.0.3","info":{"title":"Xholic API","version":"1.0.0","description":"Everything Xholic can do for an X account: context about the account, posting and scheduling, Workers, Signals, contacts, DMs and analytics. Reads use GET with query parameters; changes use POST with a JSON body. Every response has `summary` (read it first) and `data`."},"servers":[{"url":"https://api.xholic.ai/v1"}],"externalDocs":{"url":"https://docs.xholic.ai"},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key (xhk_…) from Settings → API / MCP / CLI, or an OAuth access token."}}},"x-xholic-webhook-events":{"post.published":"A scheduled or queued post went live on X.","post.failed":"X rejected a post. The payload carries the reason.","post.outperforming":"A recent post reached at least 2× the account's normal impressions. Fires once per post, after metrics sync.","post.automation_ran":"An auto-repost, auto-plug or auto-DM ran on a post.","article.published":"An X Article went live.","mention.received":"Someone mentioned the account. Arrives at the plan's mention sync cadence.","reply.received":"Someone replied to the account's post. Arrives at the sync cadence.","lead.found":"A Signals agent found a lead.","dm.received":"A direct message arrived.","dm.campaign_completed":"A DM campaign finished sending.","contacts.import_completed":"A follower or list import finished.","ask.task_completed":"A job handed to Xholic with ask_xholic or draft_with_xholic finished, failed or was cancelled.","worker.batch_ready":"A Worker run finished and drafts are waiting for review.","credits.low":"AI credits fell below 10% of the plan's monthly amount.","x_account.reconnect_needed":"X access expired. The owner must reconnect the account in Xholic.","subscription.changed":"The subscription started, ended, paused, resumed or lapsed.","connection.revoked":"An API key or OAuth app was revoked.","webhook.test":"A test event sent from Settings."},"paths":{"/me/get":{"get":{"operationId":"me.get","summary":"Who I am on X","description":"Load this before writing anything for the user. Returns the account's voice and style guide with real example lines, audience, goals, products, takes, rules, facts Xholic knows about them, connected accounts, and memory: what works for this account (lessons judged against its own normal) and notes coming up. Treat strong beliefs as facts and weak ones as hints; treat lessons and notes as evidence and material, never as rules. Never invent facts beyond these.","tags":["me"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_me","x-xholic-cli":"xholic me get","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/me/get' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic me get"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_me\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/me/get\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/me/get\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/me/get\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/me/get\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/me/get\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/me/get\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/accounts/list":{"get":{"operationId":"accounts.list","summary":"Connected X accounts","description":"List the X accounts this connection can act on (own, added and shared), with your role on each and which one is the default. Pass an account's @handle as `account` on any other tool to act on it.","tags":["accounts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"list_accounts","x-xholic-cli":"xholic accounts list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/accounts/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic accounts list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"list_accounts\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/accounts/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/accounts/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/accounts/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/accounts/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/accounts/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/accounts/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/credits/balance":{"get":{"operationId":"credits.balance","summary":"AI credits left","description":"How many Xholic AI credits are left this period (included, bonus and purchased), how many running requests hold, and when the allowance renews. Free to call. Only Xholic AI actions use credits; your own writing never does.","tags":["credits"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_credit_balance","x-xholic-cli":"xholic credits balance","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/credits/balance' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic credits balance"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_credit_balance\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/credits/balance\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/credits/balance\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/credits/balance\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/credits/balance\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/credits/balance\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/credits/balance\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/context/writing-kit":{"get":{"operationId":"context.writing_kit","summary":"Writing kit","description":"Material for writing posts in the user's voice: real posts that worked (their own winners, their circle this week, bookmarks, library outliers) to build each new post from, fresh facts and takes, and what they posted lately so you don't repeat it. Write the posts yourself from this kit, one subject per post, then run check_draft. Never copy a source post's claims or numbers as the user's own.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_writing_kit","x-xholic-cli":"xholic context writing-kit","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/context/writing-kit' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic context writing-kit"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_writing_kit\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/writing-kit\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/context/writing-kit\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/context/writing-kit\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/context/writing-kit\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/writing-kit\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/writing-kit\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"topic","in":"query","required":false,"schema":{"description":"Optional subject to pull material for.","type":"string","maxLength":200},"description":"Optional subject to pull material for."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":20}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/context/update":{"post":{"operationId":"context.update","summary":"Update account context","description":"Change the account's audience, goals, product context, topics or rules that every Xholic writer reads. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"update_account_context","x-xholic-cli":"xholic context update","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/update \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context update --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"update_account_context\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/update\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/update\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/update\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/update\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/update\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/update\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"targetAudience":{"nullable":true,"type":"string","minLength":1,"maxLength":2000},"contentGoals":{"nullable":true,"type":"string","minLength":1,"maxLength":2000},"productContext":{"nullable":true,"type":"string","minLength":1,"maxLength":6000},"selectedTopics":{"maxItems":30,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}},"accountRules":{"description":"The account's writing rules, applied to every draft: short lines such as \"No hashtags.\" At most 500 characters, so keep only the rules that matter most. Replaces the saved rules, so include any existing rules to keep. Null clears them.","nullable":true,"type":"string","minLength":1,"maxLength":500},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/profile/check":{"get":{"operationId":"profile.check","summary":"Profile check","description":"Check the account's X profile (bio, pinned post, banner, link) against what makes strangers follow, with concrete fixes.","tags":["profile"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"profile_check","x-xholic-cli":"xholic profile check","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/profile/check' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic profile check"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"profile_check\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/profile/check\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/profile/check\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/profile/check\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/profile/check\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/profile/check\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/profile/check\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/events/updates":{"get":{"operationId":"events.updates","summary":"What happened since last time","description":"Call at the start of a conversation. Returns what happened since this connection last checked: posts that went live or failed, posts doing better than usual, new leads, DMs, Worker drafts waiting, mentions and replies. Lead with what needs the user.","tags":["events"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_updates","x-xholic-cli":"xholic events updates","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/events/updates' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic events updates"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_updates\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/events/updates\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/events/updates\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/events/updates\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/events/updates\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/events/updates\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/events/updates\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"since","in":"query","required":false,"schema":{"description":"Cursor from a previous call. Leave it out to continue from the last check.","type":"string","maxLength":40},"description":"Cursor from a previous call. Leave it out to continue from the last check."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/insights/whats-working":{"get":{"operationId":"insights.whats_working","summary":"What's working","description":"What worked for the account over a period and why: best posts, formats, topics and times, compared with their normal. Use it before planning content.","tags":["insights"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"whats_working","x-xholic-cli":"xholic insights whats-working","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/insights/whats-working' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic insights whats-working"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"whats_working\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/insights/whats-working\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/insights/whats-working\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/insights/whats-working\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/insights/whats-working\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/insights/whats-working\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/insights/whats-working\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"range","in":"query","required":false,"schema":{"default":"90d","type":"string","enum":["today","7d","14d","30d","60d","90d","180d","all"]}},{"name":"timezone","in":"query","required":false,"schema":{"default":"UTC","type":"string","minLength":1,"maxLength":80}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/insights/bank":{"get":{"operationId":"insights.bank","summary":"Insight bank","description":"The account's knowledge areas and the insights Xholic mined from their posts, for teaching posts.","tags":["insights"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"insights_bank","x-xholic-cli":"xholic insights bank","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/insights/bank' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic insights bank"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"insights_bank\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/insights/bank\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/insights/bank\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/insights/bank\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/insights/bank\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/insights/bank\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/insights/bank\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"areaId","in":"query","required":false,"schema":{"description":"Only cards for this area, by its id from an earlier call.","type":"string","minLength":1,"maxLength":64},"description":"Only cards for this area, by its id from an earlier call."},{"name":"limit","in":"query","required":false,"schema":{"default":6,"type":"integer","minimum":1,"maximum":10}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/niche/now":{"get":{"operationId":"niche.now","summary":"What's working in my niche","description":"Posts proven this week in the account's circle and niche, plus bookmarks, likes and library outliers. Use as inspiration for shape and subject; never copy claims.","tags":["niche"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"niche_now","x-xholic-cli":"xholic niche now","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/niche/now' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic niche now"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"niche_now\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/niche/now\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/niche/now\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/niche/now\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/niche/now\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/niche/now\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/niche/now\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"kind","in":"query","required":false,"schema":{"default":"all","type":"string","enum":["all","proven","bookmarks","likes","library"]}},{"name":"topic","in":"query","required":false,"schema":{"description":"Narrow to posts about this, in the user's words.","type":"string","maxLength":200},"description":"Narrow to posts about this, in the user's words."},{"name":"limit","in":"query","required":false,"schema":{"default":10,"type":"integer","minimum":1,"maximum":15}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/engage/who-to-engage":{"get":{"operationId":"engage.who_to_engage","summary":"Who to engage now","description":"People worth replying to right now and why: unanswered mentions, the account's reply circle, and warm Signals leads. Write the replies yourself in the user's voice (get_me), then post with schedule_post or publish_now using replyTo only if the user asks.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"who_to_engage","x-xholic-cli":"xholic engage who-to-engage","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/engage/who-to-engage' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic engage who-to-engage"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"who_to_engage\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/who-to-engage\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/engage/who-to-engage\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/engage/who-to-engage\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/engage/who-to-engage\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/who-to-engage\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/who-to-engage\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":30}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/mentions/list":{"get":{"operationId":"mentions.list","summary":"Mentions","description":"The account's latest mentions and replies to its posts, synced by Xholic.","tags":["mentions"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"mentions_list","x-xholic-cli":"xholic mentions list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/mentions/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic mentions list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"mentions_list\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/mentions/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/mentions/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/mentions/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/mentions/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/mentions/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/mentions/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"kind","in":"query","required":false,"schema":{"default":"REPLIES","description":"\"REPLIES\" for replies to the user's posts, \"OTHER\" for other mentions, \"ALL\" for both.","type":"string","enum":["REPLIES","OTHER","ALL"]},"description":"\"REPLIES\" for replies to the user's posts, \"OTHER\" for other mentions, \"ALL\" for both."},{"name":"hideReplied","in":"query","required":false,"schema":{"default":true,"type":"boolean"}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/replies/mine":{"get":{"operationId":"replies.mine","summary":"My replies","description":"Replies the account sent, newest or best first.","tags":["replies"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"replies_mine","x-xholic-cli":"xholic replies mine","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/replies/mine' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic replies mine"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"replies_mine\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/replies/mine\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/replies/mine\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/replies/mine\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/replies/mine\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/replies/mine\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/replies/mine\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"sort","in":"query","required":false,"schema":{"default":"RECENT","type":"string","enum":["RECENT","VIEWS","LIKES","ENGAGEMENT"]}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/engage/reply-circle":{"get":{"operationId":"engage.reply_circle","summary":"Reply circle","description":"The people the account trades replies with most, and who to reply to next to grow.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"engage_reply_circle","x-xholic-cli":"xholic engage reply-circle","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/engage/reply-circle' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic engage reply-circle"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_reply_circle\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/reply-circle\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/engage/reply-circle\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/engage/reply-circle\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/engage/reply-circle\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/reply-circle\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/reply-circle\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":5,"description":"Fresh posts to return.","type":"integer","minimum":1,"maximum":10},"description":"Fresh posts to return."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/people/get":{"get":{"operationId":"people.get","summary":"Look up a person","description":"Everything about one X account: profile, recent posts, and the history with the user (replies, DMs, notes, lead status). Uses live X data when it isn't stored.","tags":["people"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_person","x-xholic-cli":"xholic people get","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/people/get?username=founder' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic people get --username 'founder'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_person\",\n  \"arguments\": {\n    \"username\": \"founder\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/people/get?username=founder\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/people/get\", {\n  params: {\n    \"username\": \"founder\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/people/get\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"username\": \"founder\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/people/get?username=founder\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/people/get?username=founder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/people/get?username=founder\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"username","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":16},"example":"founder"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/posts/get":{"get":{"operationId":"posts.get","summary":"Look up a post","description":"Any X post by id or URL with its numbers and context.","tags":["posts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_post","x-xholic-cli":"xholic posts get","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/posts/get?tweetId=%3CtweetId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic posts get --tweet-id '<tweetId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_post\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/posts/get?tweetId=%3CtweetId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/posts/get\", {\n  params: {\n    \"tweetId\": \"<tweetId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/posts/get\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"tweetId\": \"<tweetId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/posts/get?tweetId=%3CtweetId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/posts/get?tweetId=%3CtweetId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/posts/get?tweetId=%3CtweetId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"tweetId","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{6,30}$"},"example":"<tweetId>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/posts/conversation":{"get":{"operationId":"posts.conversation","summary":"Post conversation","description":"A post's thread and replies.","tags":["posts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"posts_conversation","x-xholic-cli":"xholic posts conversation","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/posts/conversation?tweetId=%3CtweetId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic posts conversation --tweet-id '<tweetId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"posts_conversation\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/posts/conversation?tweetId=%3CtweetId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/posts/conversation\", {\n  params: {\n    \"tweetId\": \"<tweetId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/posts/conversation\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"tweetId\": \"<tweetId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/posts/conversation?tweetId=%3CtweetId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/posts/conversation?tweetId=%3CtweetId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/posts/conversation?tweetId=%3CtweetId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"tweetId","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{6,30}$"},"example":"<tweetId>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/x/search":{"get":{"operationId":"x.search","summary":"Search X","description":"Live X search, one page of up to 20 posts. A sample, not every match.","tags":["x"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"search_x","x-xholic-cli":"xholic x search","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/x/search?query=build+in+public' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic x search --query 'build in public'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"search_x\",\n  \"arguments\": {\n    \"query\": \"build in public\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/x/search?query=build+in+public\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/x/search\", {\n  params: {\n    \"query\": \"build in public\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/x/search\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"query\": \"build in public\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/x/search?query=build+in+public\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/x/search?query=build+in+public\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/x/search?query=build+in+public\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":500},"example":"build in public"},{"name":"sort","in":"query","required":false,"schema":{"default":"Latest","type":"string","enum":["Latest","Top"]}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/inspiration/search":{"get":{"operationId":"inspiration.search","summary":"Search the inspiration library","description":"Search Xholic's library of proven posts by idea, with outlier scores (how far a post beat its author's normal).","tags":["inspiration"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"search_inspiration","x-xholic-cli":"xholic inspiration search","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/inspiration/search?query=build+in+public' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic inspiration search --query 'build in public'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"search_inspiration\",\n  \"arguments\": {\n    \"query\": \"build in public\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/inspiration/search?query=build+in+public\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/inspiration/search\", {\n  params: {\n    \"query\": \"build in public\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/inspiration/search\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"query\": \"build in public\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/inspiration/search?query=build+in+public\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/inspiration/search?query=build+in+public\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/inspiration/search?query=build+in+public\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200},"example":"build in public"},{"name":"timeRange","in":"query","required":false,"schema":{"default":"year","type":"string","enum":["week","month","3months","year","all"]}},{"name":"limit","in":"query","required":false,"schema":{"default":8,"type":"integer","minimum":1,"maximum":10}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/library/saved":{"get":{"operationId":"library.saved","summary":"Saved posts","description":"The account's X bookmarks and likes mirrored by Xholic, plus saved posts. Bookmarks show taste.","tags":["library"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_saved_posts","x-xholic-cli":"xholic library saved","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/library/saved' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic library saved"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_saved_posts\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/library/saved\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/library/saved\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/library/saved\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/library/saved\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/library/saved\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/library/saved\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"description":"Words to look for in the saved posts; omit for the newest.","type":"string","maxLength":120},"description":"Words to look for in the saved posts; omit for the newest."},{"name":"kind","in":"query","required":false,"schema":{"default":"all","type":"string","enum":["bookmarks","likes","all"]}},{"name":"questionsOnly","in":"query","required":false,"schema":{"default":false,"description":"Only posts that ask a question.","type":"boolean"},"description":"Only posts that ask a question."},{"name":"limit","in":"query","required":false,"schema":{"default":10,"type":"integer","minimum":1,"maximum":20}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/creators/top-posts":{"get":{"operationId":"creators.top_posts","summary":"A creator's top posts","description":"Another creator's best posts over a period.","tags":["creators"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"creators_top_posts","x-xholic-cli":"xholic creators top-posts","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/creators/top-posts?username=founder' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic creators top-posts --username 'founder'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"creators_top_posts\",\n  \"arguments\": {\n    \"username\": \"founder\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/creators/top-posts?username=founder\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/creators/top-posts\", {\n  params: {\n    \"username\": \"founder\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/creators/top-posts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"username\": \"founder\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/creators/top-posts?username=founder\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/creators/top-posts?username=founder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/creators/top-posts?username=founder\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"username","in":"query","required":true,"schema":{"type":"string","pattern":"^@?[A-Za-z0-9_]{1,15}$"},"example":"founder"},{"name":"range","in":"query","required":false,"schema":{"default":"90d","type":"string","enum":["30d","90d","180d","all"]}},{"name":"limit","in":"query","required":false,"schema":{"default":8,"type":"integer","minimum":1,"maximum":10}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/drafts/check":{"get":{"operationId":"drafts.check","summary":"Check a draft","description":"Free checks before posting: length for the account's X tier, links (Xholic drafts never contain links), near-copies of a source post, repeats of what the account posted recently, and thread structure. Run it on every draft you write; fix what it flags.","tags":["drafts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"check_draft","x-xholic-cli":"xholic drafts check","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/drafts/check?text=Shipping+the+API+today' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic drafts check --text 'Shipping the API today'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"check_draft\",\n  \"arguments\": {\n    \"text\": \"Shipping the API today\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/drafts/check?text=Shipping+the+API+today\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/drafts/check\", {\n  params: {\n    \"text\": \"Shipping the API today\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/drafts/check\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"text\": \"Shipping the API today\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/drafts/check?text=Shipping+the+API+today\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/drafts/check?text=Shipping+the+API+today\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/drafts/check?text=Shipping+the+API+today\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"text","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":25000},"example":"Shipping the API today"},{"name":"threadParts","in":"query","required":false,"schema":{"description":"For a thread: every part in order, starting with the same first post as text.","minItems":2,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":25000}},"description":"For a thread: every part in order, starting with the same first post as text."},{"name":"sourceText","in":"query","required":false,"schema":{"description":"The post you built from, to catch near-copies.","type":"string","maxLength":25000},"description":"The post you built from, to catch near-copies."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/drafts/save":{"post":{"operationId":"drafts.save","summary":"Save a draft","description":"Save a post or thread as a draft in Xholic. Nothing is posted. A draft is not a post: never tell the user it was posted.","tags":["drafts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"save_draft","x-xholic-cli":"xholic drafts save","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/drafts/save \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Shipping the API today\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic drafts save --text 'Shipping the API today' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"save_draft\",\n  \"arguments\": {\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/drafts/save\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/drafts/save\",\n  {\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/drafts/save\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"text\": \"Shipping the API today\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"text\":\"Shipping the API today\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/drafts/save\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/drafts/save\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"text\":\"Shipping the API today\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/drafts/save\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"text\":\"Shipping the API today\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":25000},"threadParts":{"minItems":2,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":25000}},"timezone":{"default":"UTC","type":"string","minLength":1,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["text"]},"example":{"text":"Shipping the API today","dryRun":true}}}}}},"/posts/schedule":{"post":{"operationId":"posts.schedule","summary":"Schedule a post","description":"Schedule a post or thread on X at a time. Supports media and automations. Call it only when the user asked for this in the conversation; never on your own initiative. It spends a post credit when it goes live.","tags":["posts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"schedule_post","x-xholic-cli":"xholic posts schedule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/posts/schedule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Shipping the API today\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic posts schedule --text 'Shipping the API today' --scheduled-at '2026-11-03T09:00' --timezone 'America/New_York' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"schedule_post\",\n  \"arguments\": {\n    \"text\": \"Shipping the API today\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/posts/schedule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"text\": \"Shipping the API today\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/posts/schedule\",\n  {\n    \"text\": \"Shipping the API today\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/posts/schedule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"text\": \"Shipping the API today\",\n        \"scheduledAt\": \"2026-11-03T09:00\",\n        \"timezone\": \"America/New_York\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"text\":\"Shipping the API today\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/posts/schedule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/posts/schedule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"text\":\"Shipping the API today\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/posts/schedule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"text\":\"Shipping the API today\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":25000},"threadParts":{"description":"For a thread: every part in order, starting with the same first post as text.","minItems":2,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":25000}},"scheduledAt":{"type":"string","minLength":1,"maxLength":40,"description":"When to post: the user's local date and time such as 2026-10-25T10:00 (then pass timezone), or an ISO time with offset."},"timezone":{"type":"string","minLength":1,"maxLength":80,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"media":{"description":"Media from upload_media, by mediaId. Up to 4 images, or 1 GIF or video.","maxItems":4,"type":"array","items":{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":200}},"required":["mediaId"],"additionalProperties":{}}},"automation":{"description":"Post automations (auto-repost, auto-plug reply, auto-delete, auto-DM). Shape as in the docs: docs.xholic.ai/api/automations.","type":"object","properties":{},"additionalProperties":{}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["text","scheduledAt","timezone"]},"example":{"text":"Shipping the API today","scheduledAt":"2026-11-03T09:00","timezone":"America/New_York","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/posts/publish-now":{"post":{"operationId":"posts.publish_now","summary":"Post now","description":"Post to X immediately. Requires idempotencyKey so a retry can never post twice. Call it only when the user asked for this in the conversation; never on your own initiative. Spends a post credit.","tags":["posts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"publish_now","x-xholic-cli":"xholic posts publish-now","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/posts/publish-now \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic posts publish-now --text 'Shipping the API today' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"publish_now\",\n  \"arguments\": {\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/posts/publish-now\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/posts/publish-now\",\n  {\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/posts/publish-now\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"text\": \"Shipping the API today\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/posts/publish-now\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/posts/publish-now\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/posts/publish-now\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":25000},"threadParts":{"description":"For a thread: every part in order, starting with the same first post as text.","minItems":2,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":25000}},"media":{"description":"Media from upload_media, by mediaId. Up to 4 images, or 1 GIF or video.","maxItems":4,"type":"array","items":{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":200}},"required":["mediaId"],"additionalProperties":{}}},"automation":{"description":"Post automations (auto-repost, auto-plug reply, auto-delete, auto-DM). Shape as in the docs: docs.xholic.ai/api/automations.","type":"object","properties":{},"additionalProperties":{}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["text"]},"example":{"text":"Shipping the API today","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/queue/list":{"get":{"operationId":"queue.list","summary":"Queue and drafts","description":"Scheduled posts and drafts, soonest first.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_queue","x-xholic-cli":"xholic queue list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/queue/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic queue list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_queue\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/queue/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/queue/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/queue/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"view","in":"query","required":false,"schema":{"default":"all","type":"string","enum":["all","queued","drafts","posted","failed"]}},{"name":"limit","in":"query","required":false,"schema":{"default":10,"type":"integer","minimum":1,"maximum":20}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/queue/reschedule":{"post":{"operationId":"queue.reschedule","summary":"Reschedule a post","description":"Move a queued post to a new time. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"reschedule_post","x-xholic-cli":"xholic queue reschedule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/reschedule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue reschedule --post-id '<postId>' --scheduled-at '2026-11-03T09:00' --timezone 'America/New_York' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"reschedule_post\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/reschedule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/reschedule\",\n  {\n    \"postId\": \"<postId>\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/reschedule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"scheduledAt\": \"2026-11-03T09:00\",\n        \"timezone\": \"America/New_York\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/reschedule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/reschedule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/reschedule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"scheduledAt":{"type":"string","description":"The local date and time in timezone, such as 2026-10-25T10:00. Write the time the user means; do not convert it to UTC or add an offset."},"timezone":{"type":"string","minLength":1,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId","scheduledAt","timezone"]},"example":{"postId":"<postId>","scheduledAt":"2026-11-03T09:00","timezone":"America/New_York","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/queue/unschedule":{"post":{"operationId":"queue.unschedule","summary":"Unschedule a post","description":"Take a scheduled post out of the queue and keep it as a draft.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"unschedule_post","x-xholic-cli":"xholic queue unschedule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/unschedule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue unschedule --post-id '<postId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"unschedule_post\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/unschedule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/unschedule\",\n  {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/unschedule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/unschedule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/unschedule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/unschedule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId"]},"example":{"postId":"<postId>","dryRun":true}}}}}},"/queue/edit":{"post":{"operationId":"queue.edit","summary":"Edit a queued post","description":"Change the text, thread, media or automations of a draft or scheduled post.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"edit_queued_post","x-xholic-cli":"xholic queue edit","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/edit \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue edit --post-id '<postId>' --text 'Shipping the API today' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"edit_queued_post\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/edit\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/edit\",\n  {\n    \"postId\": \"<postId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/edit\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"text\": \"Shipping the API today\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/edit\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/edit\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/edit\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120},"text":{"type":"string","minLength":1,"maxLength":25000},"threadParts":{"description":"For a thread: every part in order, starting with the same first post as text.","minItems":2,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":25000}},"media":{"description":"Media from upload_media, by mediaId. Up to 4 images, or 1 GIF or video.","maxItems":4,"type":"array","items":{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":200}},"required":["mediaId"],"additionalProperties":{}}},"automation":{"description":"Post automations (auto-repost, auto-plug reply, auto-delete, auto-DM). Shape as in the docs: docs.xholic.ai/api/automations.","type":"object","properties":{},"additionalProperties":{}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId","text"]},"example":{"postId":"<postId>","text":"Shipping the API today","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/queue/delete":{"post":{"operationId":"queue.delete","summary":"Delete a draft or scheduled post","description":"Delete a draft or scheduled post from Xholic. It does not delete anything already on X. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"delete_queued_post","x-xholic-cli":"xholic queue delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue delete --post-id '<postId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"delete_queued_post\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/delete\",\n  {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId"]},"example":{"postId":"<postId>","dryRun":true}}}}}},"/media/create-upload":{"post":{"operationId":"media.create_upload","summary":"Upload media","description":"Start a media upload (image, GIF or video). Returns a mediaId and an upload URL; PUT the file bytes there, then call media.complete_upload. Video works too.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"upload_media","x-xholic-cli":"xholic media create-upload","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/media/create-upload \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"originalFilename\":\"<originalFilename>\",\"mimeType\":\"<mimeType>\",\"byteSize\":1,\"kind\":\"IMAGE\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic media create-upload --original-filename '<originalFilename>' --mime-type '<mimeType>' --byte-size 1 --kind 'IMAGE' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"upload_media\",\n  \"arguments\": {\n    \"originalFilename\": \"<originalFilename>\",\n    \"mimeType\": \"<mimeType>\",\n    \"byteSize\": 1,\n    \"kind\": \"IMAGE\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/create-upload\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"originalFilename\": \"<originalFilename>\",\n    \"mimeType\": \"<mimeType>\",\n    \"byteSize\": 1,\n    \"kind\": \"IMAGE\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/media/create-upload\",\n  {\n    \"originalFilename\": \"<originalFilename>\",\n    \"mimeType\": \"<mimeType>\",\n    \"byteSize\": 1,\n    \"kind\": \"IMAGE\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/media/create-upload\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"originalFilename\": \"<originalFilename>\",\n        \"mimeType\": \"<mimeType>\",\n        \"byteSize\": 1,\n        \"kind\": \"IMAGE\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"originalFilename\":\"<originalFilename>\",\"mimeType\":\"<mimeType>\",\"byteSize\":1,\"kind\":\"IMAGE\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/media/create-upload\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/create-upload\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"originalFilename\":\"<originalFilename>\",\"mimeType\":\"<mimeType>\",\"byteSize\":1,\"kind\":\"IMAGE\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/create-upload\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"originalFilename\":\"<originalFilename>\",\"mimeType\":\"<mimeType>\",\"byteSize\":1,\"kind\":\"IMAGE\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"originalFilename":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":3,"maxLength":100},"byteSize":{"type":"integer","exclusiveMinimum":true,"maximum":536870912},"kind":{"type":"string","enum":["IMAGE","VIDEO"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["originalFilename","mimeType","byteSize","kind"]},"example":{"originalFilename":"<originalFilename>","mimeType":"<mimeType>","byteSize":1,"kind":"IMAGE","dryRun":true}}}}}},"/media/complete-upload":{"post":{"operationId":"media.complete_upload","summary":"Finish a media upload","description":"Mark an upload finished after the bytes were PUT to the upload URL. Multipart uploads pass their parts.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"media_complete_upload","x-xholic-cli":"xholic media complete-upload","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/media/complete-upload \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"mediaId\":\"<mediaId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic media complete-upload --media-id '<mediaId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"media_complete_upload\",\n  \"arguments\": {\n    \"mediaId\": \"<mediaId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/complete-upload\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"mediaId\": \"<mediaId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/media/complete-upload\",\n  {\n    \"mediaId\": \"<mediaId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/media/complete-upload\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"mediaId\": \"<mediaId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"mediaId\":\"<mediaId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/media/complete-upload\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/complete-upload\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"mediaId\":\"<mediaId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/complete-upload\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"mediaId\":\"<mediaId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":200},"parts":{"maxItems":10000,"type":"array","items":{"type":"object","properties":{"partNumber":{"type":"integer","minimum":1,"maximum":9007199254740991},"etag":{"type":"string","minLength":1,"maxLength":256}},"required":["partNumber","etag"]}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["mediaId"]},"example":{"mediaId":"<mediaId>","dryRun":true}}}}}},"/content/export":{"get":{"operationId":"content.export","summary":"Export content","description":"The account's posts with their numbers for a period, as data you can analyse.","tags":["content"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"content_export","x-xholic-cli":"xholic content export","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/content/export' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic content export"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"content_export\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/content/export\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/content/export\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/content/export\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/content/export\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/content/export\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/content/export\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"range","in":"query","required":false,"schema":{"default":"30d","type":"string","enum":["today","7d","14d","30d","60d","90d","180d","all"]}},{"name":"timezone","in":"query","required":false,"schema":{"default":"UTC","type":"string","minLength":1,"maxLength":80}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/summary":{"get":{"operationId":"analytics.summary","summary":"Analytics","description":"Totals and a daily series for a period: impressions, engagement, followers, posts and replies counted separately.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_analytics","x-xholic-cli":"xholic analytics summary","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/summary' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics summary"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_analytics\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/summary\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/summary\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/summary\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/summary\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/summary\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/summary\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"range","in":"query","required":false,"schema":{"default":"30d","type":"string","enum":["today","7d","14d","30d","60d","90d","180d","all"]}},{"name":"timezone","in":"query","required":false,"schema":{"default":"UTC","type":"string","minLength":1,"maxLength":80}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/content":{"get":{"operationId":"analytics.content","summary":"How posts did","description":"How the account's posts performed, compared with its normal. Search for one post or sort a period.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"how_did_it_do","x-xholic-cli":"xholic analytics content","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/content' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics content"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"how_did_it_do\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/content\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/content\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/content\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/content\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/content\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/content\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"range","in":"query","required":false,"schema":{"default":"30d","type":"string","enum":["today","7d","14d","30d","60d","90d","180d","all"]}},{"name":"timezone","in":"query","required":false,"schema":{"default":"UTC","type":"string","minLength":1,"maxLength":80}},{"name":"search","in":"query","required":false,"schema":{"default":"","type":"string","maxLength":100}},{"name":"sort","in":"query","required":false,"schema":{"default":"impressions","type":"string","enum":["publishedAt","impressions","engagements","engagementRate","likes","replies","reposts","bookmarks"]}},{"name":"limit","in":"query","required":false,"schema":{"default":10,"type":"integer","minimum":1,"maximum":20}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/memory/remember":{"post":{"operationId":"memory.remember","summary":"Remember","description":"Save a lasting fact, writing preference or answer about the user to the memory every Xholic writer reads. Only things the user told you or confirmed. For something to do later (post like this Thursday, a test, a plan), use add_note instead.","tags":["memory"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"remember","x-xholic-cli":"xholic memory remember","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/memory/remember \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"fact\":\"<fact>\",\"kind\":\"WRITING\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic memory remember --fact '<fact>' --kind 'WRITING' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remember\",\n  \"arguments\": {\n    \"fact\": \"<fact>\",\n    \"kind\": \"WRITING\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/memory/remember\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"fact\": \"<fact>\",\n    \"kind\": \"WRITING\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/memory/remember\",\n  {\n    \"fact\": \"<fact>\",\n    \"kind\": \"WRITING\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/memory/remember\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"fact\": \"<fact>\",\n        \"kind\": \"WRITING\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"fact\":\"<fact>\",\"kind\":\"WRITING\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/memory/remember\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/memory/remember\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"fact\":\"<fact>\",\"kind\":\"WRITING\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/memory/remember\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"fact\":\"<fact>\",\"kind\":\"WRITING\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fact":{"type":"string","minLength":3,"maxLength":300},"kind":{"type":"string","enum":["WRITING","FACT","ANSWER"],"description":"WRITING: how they want their posts, replies or DMs written (tone, words, emoji, length, format). FACT: something true about them, their business, product, prices or audience. ANSWER: how they want Ask itself to answer them (format, language, detail)."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["fact","kind"]},"example":{"fact":"<fact>","kind":"WRITING","dryRun":true}}}}}},"/memory/forget":{"post":{"operationId":"memory.forget","summary":"Forget","description":"Remove a memory the user says is wrong or outdated.","tags":["memory"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"forget","x-xholic-cli":"xholic memory forget","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/memory/forget \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"memoryId\":\"<memoryId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic memory forget --memory-id '<memoryId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"forget\",\n  \"arguments\": {\n    \"memoryId\": \"<memoryId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/memory/forget\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"memoryId\": \"<memoryId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/memory/forget\",\n  {\n    \"memoryId\": \"<memoryId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/memory/forget\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"memoryId\": \"<memoryId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"memoryId\":\"<memoryId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/memory/forget\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/memory/forget\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"memoryId\":\"<memoryId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/memory/forget\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"memoryId\":\"<memoryId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"memoryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"fact":{"description":"The memory's text, shown on the approval card.","type":"string","maxLength":300},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["memoryId"]},"example":{"memoryId":"<memoryId>","dryRun":true}}}}}},"/workers/list":{"get":{"operationId":"workers.list","summary":"Workers","description":"The account's Workers (always-on AI writers): settings, schedule and status.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_workers","x-xholic-cli":"xholic workers list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/workers/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic workers list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_workers\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/workers/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/workers/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/workers/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/workers/drafts":{"get":{"operationId":"workers.drafts","summary":"Worker drafts","description":"Drafts a Worker wrote that are waiting for review.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_worker_drafts","x-xholic-cli":"xholic workers drafts","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/workers/drafts' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic workers drafts"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_worker_drafts\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/drafts\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/workers/drafts\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/workers/drafts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/workers/drafts\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/drafts\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/drafts\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"neuronId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"schema":{"default":12,"type":"integer","minimum":1,"maximum":30}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/workers/overview":{"get":{"operationId":"workers.overview","summary":"Growth overview","description":"The account's growth overview: milestones, Workers and what they produced.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"workers_overview","x-xholic-cli":"xholic workers overview","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/workers/overview' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic workers overview"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_overview\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/overview\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/workers/overview\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/workers/overview\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/workers/overview\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/overview\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/overview\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/workers/find-creators":{"get":{"operationId":"workers.find_creators","summary":"Find creators for a Worker","description":"Find X creators whose style a Worker can learn from.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"workers_find_creators","x-xholic-cli":"xholic workers find-creators","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/workers/find-creators' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic workers find-creators"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_find_creators\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/find-creators\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/workers/find-creators\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/workers/find-creators\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/workers/find-creators\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/find-creators\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/find-creators\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","minLength":2,"maxLength":60}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/workers/create":{"post":{"operationId":"workers.create","summary":"Create a Worker","description":"Create a Worker that writes posts on a schedule or on demand. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"create_worker","x-xholic-cli":"xholic workers create","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/create \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"voiceMode\":\"OWN\",\"topicMode\":\"FOR_YOU\",\"outputCount\":8,\"scheduleMode\":\"ON_DEMAND\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers create --name 'Example' --voice-mode 'OWN' --topic-mode 'FOR_YOU' --output-count 8 --schedule-mode 'ON_DEMAND' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"create_worker\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"voiceMode\": \"OWN\",\n    \"topicMode\": \"FOR_YOU\",\n    \"outputCount\": 8,\n    \"scheduleMode\": \"ON_DEMAND\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/create\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"voiceMode\": \"OWN\",\n    \"topicMode\": \"FOR_YOU\",\n    \"outputCount\": 8,\n    \"scheduleMode\": \"ON_DEMAND\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/create\",\n  {\n    \"name\": \"Example\",\n    \"voiceMode\": \"OWN\",\n    \"topicMode\": \"FOR_YOU\",\n    \"outputCount\": 8,\n    \"scheduleMode\": \"ON_DEMAND\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/create\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"voiceMode\": \"OWN\",\n        \"topicMode\": \"FOR_YOU\",\n        \"outputCount\": 8,\n        \"scheduleMode\": \"ON_DEMAND\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"voiceMode\":\"OWN\",\"topicMode\":\"FOR_YOU\",\"outputCount\":8,\"scheduleMode\":\"ON_DEMAND\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/create\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/create\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"voiceMode\":\"OWN\",\"topicMode\":\"FOR_YOU\",\"outputCount\":8,\"scheduleMode\":\"ON_DEMAND\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/create\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"voiceMode\":\"OWN\",\"topicMode\":\"FOR_YOU\",\"outputCount\":8,\"scheduleMode\":\"ON_DEMAND\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"status":{"default":"ACTIVE","type":"string","enum":["ACTIVE","PAUSED"],"description":"PAUSED saves the worker without running it, for when the plan's active workers are all in use."},"voiceMode":{"type":"string","enum":["OWN","CREATOR","HYBRID"],"description":"OWN is \"My voice\"; CREATOR writes in the creators' style; HYBRID is the user's voice with the creators' rhythm."},"creatorXIds":{"default":[],"maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"description":"Creator xid values from findWorkerCreators: one for HYBRID unless the user asks for more (up to three), one to three for CREATOR, none for OWN."},"instructions":{"description":"The worker's brief, broad boundaries only: who it writes for, who speaks, how the account likes to write, the areas it usually writes in, when to mention products and hard bans. Never a thesis, a point of view to push or specific topics to cover.","nullable":true,"type":"string","maxLength":2000},"applyAccountRules":{"default":true,"type":"boolean","description":"Follow the account's saved writing rules."},"mirrorProvenPosts":{"default":true,"type":"boolean","description":"Shape posts on formats that already work in the niche."},"topicMode":{"type":"string","enum":["FOR_YOU","PRODUCT","CUSTOM_TOPIC","NICHE_TRENDING"],"description":"FOR_YOU is \"For you\" (topics from the profile); PRODUCT is \"Your products\"; CUSTOM_TOPIC is a custom topic; NICHE_TRENDING follows what is trending for its keywords."},"customTopic":{"description":"CUSTOM_TOPIC: what to post about. NICHE_TRENDING: one to five comma-separated keywords.","nullable":true,"type":"string","maxLength":500},"productIds":{"default":[],"maxItems":5,"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"description":"PRODUCT only: saved product IDs from getAutomationSetup or getAccountContext."},"outputCount":{"anyOf":[{"type":"number","enum":[8]},{"type":"number","enum":[12]},{"type":"number","enum":[24]}],"description":"Posts written per run: 8, 12 or 24."},"scheduleMode":{"type":"string","enum":["ON_DEMAND","DAILY","WEEKLY"]},"scheduleTimeMinutes":{"description":"DAILY or WEEKLY: minutes after midnight in the account's timezone, e.g. 540 for 9:00.","nullable":true,"type":"integer","minimum":0,"maximum":1439},"scheduleDayOfWeek":{"description":"WEEKLY: 0 is Sunday, 6 is Saturday.","nullable":true,"type":"integer","minimum":0,"maximum":6},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name","voiceMode","topicMode","outputCount","scheduleMode"]},"example":{"name":"Example","voiceMode":"OWN","topicMode":"FOR_YOU","outputCount":8,"scheduleMode":"ON_DEMAND","dryRun":true}}}}}},"/workers/update":{"post":{"operationId":"workers.update","summary":"Edit a Worker","description":"Change a Worker's instructions, voice, topics, products, size or schedule. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"update_worker","x-xholic-cli":"xholic workers update","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/update \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"workerId\":\"<workerId>\",\"changes\":{},\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers update --worker-id '<workerId>' --changes '{}' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"update_worker\",\n  \"arguments\": {\n    \"workerId\": \"<workerId>\",\n    \"changes\": {},\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/update\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"workerId\": \"<workerId>\",\n    \"changes\": {},\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/update\",\n  {\n    \"workerId\": \"<workerId>\",\n    \"changes\": {},\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/update\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"workerId\": \"<workerId>\",\n        \"changes\": {},\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"workerId\":\"<workerId>\",\"changes\":{},\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/update\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/update\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"workerId\":\"<workerId>\",\"changes\":{},\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/update\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"workerId\":\"<workerId>\",\"changes\":{},\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"changes":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"status":{"type":"string","enum":["ACTIVE","PAUSED"],"description":"PAUSED saves the worker without running it, for when the plan's active workers are all in use."},"voiceMode":{"type":"string","enum":["OWN","CREATOR","HYBRID"],"description":"OWN is \"My voice\"; CREATOR writes in the creators' style; HYBRID is the user's voice with the creators' rhythm."},"creatorXIds":{"maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"description":"Creator xid values from findWorkerCreators: one for HYBRID unless the user asks for more (up to three), one to three for CREATOR, none for OWN."},"instructions":{"description":"The worker's brief, broad boundaries only: who it writes for, who speaks, how the account likes to write, the areas it usually writes in, when to mention products and hard bans. Never a thesis, a point of view to push or specific topics to cover.","nullable":true,"type":"string","maxLength":2000},"applyAccountRules":{"type":"boolean","description":"Follow the account's saved writing rules."},"mirrorProvenPosts":{"type":"boolean","description":"Shape posts on formats that already work in the niche."},"topicMode":{"type":"string","enum":["FOR_YOU","PRODUCT","CUSTOM_TOPIC","NICHE_TRENDING"],"description":"FOR_YOU is \"For you\" (topics from the profile); PRODUCT is \"Your products\"; CUSTOM_TOPIC is a custom topic; NICHE_TRENDING follows what is trending for its keywords."},"customTopic":{"description":"CUSTOM_TOPIC: what to post about. NICHE_TRENDING: one to five comma-separated keywords.","nullable":true,"type":"string","maxLength":500},"productIds":{"maxItems":5,"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"description":"PRODUCT only: saved product IDs from getAutomationSetup or getAccountContext."},"outputCount":{"anyOf":[{"type":"number","enum":[8]},{"type":"number","enum":[12]},{"type":"number","enum":[24]}],"description":"Posts written per run: 8, 12 or 24."},"scheduleMode":{"type":"string","enum":["ON_DEMAND","DAILY","WEEKLY"]},"scheduleTimeMinutes":{"description":"DAILY or WEEKLY: minutes after midnight in the account's timezone, e.g. 540 for 9:00.","nullable":true,"type":"integer","minimum":0,"maximum":1439},"scheduleDayOfWeek":{"description":"WEEKLY: 0 is Sunday, 6 is Saturday.","nullable":true,"type":"integer","minimum":0,"maximum":6}}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["workerId","changes"]},"example":{"workerId":"<workerId>","changes":{},"dryRun":true}}}}}},"/workers/set-status":{"post":{"operationId":"workers.set_status","summary":"Pause or resume a Worker","description":"Pause or resume a Worker.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"pause_or_resume_worker","x-xholic-cli":"xholic workers set-status","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/set-status \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"workerId\":\"<workerId>\",\"status\":\"ACTIVE\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers set-status --worker-id '<workerId>' --status 'ACTIVE' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"pause_or_resume_worker\",\n  \"arguments\": {\n    \"workerId\": \"<workerId>\",\n    \"status\": \"ACTIVE\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/set-status\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"workerId\": \"<workerId>\",\n    \"status\": \"ACTIVE\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/set-status\",\n  {\n    \"workerId\": \"<workerId>\",\n    \"status\": \"ACTIVE\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/set-status\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"workerId\": \"<workerId>\",\n        \"status\": \"ACTIVE\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"workerId\":\"<workerId>\",\"status\":\"ACTIVE\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/set-status\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/set-status\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"workerId\":\"<workerId>\",\"status\":\"ACTIVE\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/set-status\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"workerId\":\"<workerId>\",\"status\":\"ACTIVE\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["ACTIVE","PAUSED"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["workerId","status"]},"example":{"workerId":"<workerId>","status":"ACTIVE","dryRun":true}}}}}},"/workers/run":{"post":{"operationId":"workers.run","summary":"Run a Worker now","description":"Queue a Worker to write a new batch now with Xholic's writer. Spends Xholic AI credits per post: quote first, show it to the user, and pass confirmCredits after they agree. Returns right away; drafts arrive in get_worker_drafts.\n\nUses Xholic AI credits (up to about 120). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"run_worker","x-xholic-cli":"xholic workers run","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/run \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"neuronId\":\"<neuronId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers run --neuron-id '<neuronId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"run_worker\",\n  \"arguments\": {\n    \"neuronId\": \"<neuronId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/run\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"neuronId\": \"<neuronId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/run\",\n  {\n    \"neuronId\": \"<neuronId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/run\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"neuronId\": \"<neuronId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"neuronId\":\"<neuronId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/run\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/run\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"neuronId\":\"<neuronId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/run\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"neuronId\":\"<neuronId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"neuronId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["neuronId"]},"example":{"neuronId":"<neuronId>","dryRun":true}}}}}},"/leads/list":{"get":{"operationId":"leads.list","summary":"Leads","description":"Leads found by the account's Signals agents, hottest first, with why each one fits.","tags":["leads"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_leads","x-xholic-cli":"xholic leads list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/leads/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic leads list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_leads\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/leads/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/leads/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/leads/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/leads/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/leads/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/leads/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"agentId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"status","in":"query","required":false,"schema":{"default":"ALL","type":"string","enum":["ALL","COLLECTED","CONTACTED","DISMISSED"]}},{"name":"limit","in":"query","required":false,"schema":{"default":10,"type":"integer","minimum":1,"maximum":20}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/automation-setup":{"get":{"operationId":"signals.automation_setup","summary":"Agents set up on the account","description":"Every Worker and Signals agent with its settings, for planning changes.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_automation_setup","x-xholic-cli":"xholic signals automation-setup","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/automation-setup' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals automation-setup"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_automation_setup\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/automation-setup\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/automation-setup\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/automation-setup\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/automation-setup\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/automation-setup\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/automation-setup\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/customer-brief":{"get":{"operationId":"signals.customer_brief","summary":"Customer brief","description":"Who the account's customers are, what they ask, and where to find them, from Signals.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_customer_brief","x-xholic-cli":"xholic signals customer-brief","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/customer-brief' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals customer-brief"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_customer_brief\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/customer-brief\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/customer-brief\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/customer-brief\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/customer-brief\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/customer-brief\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/customer-brief\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/draft-audience":{"get":{"operationId":"signals.draft_audience","summary":"Draft a lead audience","description":"Draft who a Signals agent should find, from a product, a URL or a description.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_draft_audience","x-xholic-cli":"xholic signals draft-audience","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/draft-audience?mode=product' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals draft-audience --mode 'product'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_draft_audience\",\n  \"arguments\": {\n    \"mode\": \"product\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/draft-audience?mode=product\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/draft-audience\", {\n  params: {\n    \"mode\": \"product\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/draft-audience\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"mode\": \"product\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/draft-audience?mode=product\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/draft-audience?mode=product\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/draft-audience?mode=product\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"mode","in":"query","required":true,"schema":{"type":"string","enum":["product","website","refine"]},"example":"product"},{"name":"productId","in":"query","required":false,"schema":{"description":"mode product: the saved product's ID.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"mode product: the saved product's ID."},{"name":"url","in":"query","required":false,"schema":{"description":"mode website: the site to read.","type":"string","minLength":3,"maxLength":2048},"description":"mode website: the site to read."},{"name":"audienceDescription","in":"query","required":false,"schema":{"description":"mode refine: the audience description to sharpen.","type":"string","minLength":5,"maxLength":3000},"description":"mode refine: the audience description to sharpen."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/suggest-sources":{"get":{"operationId":"signals.suggest_sources","summary":"Suggest lead sources","description":"Suggest keywords, profiles and lists a Signals agent should watch.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_suggest_sources","x-xholic-cli":"xholic signals suggest-sources","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/suggest-sources?audienceDescription=%3CaudienceDescription%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals suggest-sources --audience-description '<audienceDescription>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_suggest_sources\",\n  \"arguments\": {\n    \"audienceDescription\": \"<audienceDescription>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/suggest-sources?audienceDescription=%3CaudienceDescription%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/suggest-sources\", {\n  params: {\n    \"audienceDescription\": \"<audienceDescription>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/suggest-sources\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"audienceDescription\": \"<audienceDescription>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/suggest-sources?audienceDescription=%3CaudienceDescription%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/suggest-sources?audienceDescription=%3CaudienceDescription%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/suggest-sources?audienceDescription=%3CaudienceDescription%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"audienceDescription","in":"query","required":true,"schema":{"type":"string","minLength":5,"maxLength":3000},"example":"<audienceDescription>"},{"name":"rubric","in":"query","required":false,"schema":{"nullable":true,"type":"object","properties":{"who":{"type":"string","minLength":1,"maxLength":600},"needs":{"default":[],"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"disqualifiers":{"default":[],"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"exampleMatch":{"default":null,"nullable":true,"type":"string","maxLength":600},"exampleNonMatch":{"default":null,"nullable":true,"type":"string","maxLength":600}},"required":["who"]}},{"name":"productId","in":"query","required":false,"schema":{"nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"existing","in":"query","required":false,"schema":{"maxItems":15,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["KEYWORD"]},"query":{"type":"string","minLength":2,"maxLength":500}},"required":["type","query"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["PROFILE_ENGAGERS"]},"username":{"type":"string"},"includeReplies":{"default":true,"type":"boolean"},"includeQuotes":{"default":true,"type":"boolean"},"includeReposts":{"default":true,"type":"boolean"}},"required":["type","username"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["FOLLOWERS"]},"username":{"type":"string"}},"required":["type","username"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["LIST_MEMBERS"]},"listId":{"type":"string","minLength":1,"maxLength":64},"listUrl":{"nullable":true,"type":"string","maxLength":2048,"format":"uri"}},"required":["type","listId"]}]}}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/test-searches":{"get":{"operationId":"signals.test_searches","summary":"Test lead searches","description":"Try search queries on live X before an agent uses them.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_test_searches","x-xholic-cli":"xholic signals test-searches","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/test-searches?queries=%3Cquerie%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals test-searches --queries '<querie>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_test_searches\",\n  \"arguments\": {\n    \"queries\": [\n      \"<querie>\"\n    ]\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/test-searches?queries=%3Cquerie%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/test-searches\", {\n  params: {\n    \"queries\": [\n      \"<querie>\"\n    ]\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/test-searches\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"queries\": [\n            \"<querie>\"\n        ]\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/test-searches?queries=%3Cquerie%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/test-searches?queries=%3Cquerie%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/test-searches?queries=%3Cquerie%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"queries","in":"query","required":true,"schema":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"string","minLength":2,"maxLength":500}},"example":["<querie>"]},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/create-agent":{"post":{"operationId":"signals.create_agent","summary":"Create a Signals agent","description":"Create an always-on agent that finds leads on X from sources and an audience description. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"create_signal_agent","x-xholic-cli":"xholic signals create-agent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/create-agent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"audienceDescription\":\"<audienceDescription>\",\"sources\":[{\"type\":\"KEYWORD\",\"query\":\"build in public\"}],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals create-agent --name 'Example' --audience-description '<audienceDescription>' --sources '[{\"type\":\"KEYWORD\",\"query\":\"build in public\"}]' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"create_signal_agent\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"audienceDescription\": \"<audienceDescription>\",\n    \"sources\": [\n      {\n        \"type\": \"KEYWORD\",\n        \"query\": \"build in public\"\n      }\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/create-agent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"audienceDescription\": \"<audienceDescription>\",\n    \"sources\": [\n      {\n        \"type\": \"KEYWORD\",\n        \"query\": \"build in public\"\n      }\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/create-agent\",\n  {\n    \"name\": \"Example\",\n    \"audienceDescription\": \"<audienceDescription>\",\n    \"sources\": [\n      {\n        \"type\": \"KEYWORD\",\n        \"query\": \"build in public\"\n      }\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/create-agent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"audienceDescription\": \"<audienceDescription>\",\n        \"sources\": [\n            {\n                \"type\": \"KEYWORD\",\n                \"query\": \"build in public\"\n            }\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"audienceDescription\":\"<audienceDescription>\",\"sources\":[{\"type\":\"KEYWORD\",\"query\":\"build in public\"}],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/create-agent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/create-agent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"audienceDescription\":\"<audienceDescription>\",\"sources\":[{\"type\":\"KEYWORD\",\"query\":\"build in public\"}],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/create-agent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"audienceDescription\":\"<audienceDescription>\",\"sources\":[{\"type\":\"KEYWORD\",\"query\":\"build in public\"}],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"productId":{"nullable":true,"type":"string","minLength":1,"maxLength":160},"audienceDescription":{"type":"string","minLength":20,"maxLength":3000},"exclusions":{"nullable":true,"type":"string","maxLength":1500},"rubric":{"nullable":true,"type":"object","properties":{"who":{"type":"string","minLength":1,"maxLength":600},"needs":{"default":[],"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"disqualifiers":{"default":[],"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"exampleMatch":{"default":null,"nullable":true,"type":"string","maxLength":600},"exampleNonMatch":{"default":null,"nullable":true,"type":"string","maxLength":600}},"required":["who"]},"strictness":{"default":"HIGH_PRECISION","type":"string","enum":["HIGH_PRECISION","DISCOVERY"]},"dmPolicy":{"default":"ANYONE","type":"string","enum":["ANYONE","OPEN_DMS_ONLY"]},"destinationListId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"baselineMode":{"default":"FUTURE_ONLY","type":"string","enum":["FUTURE_ONLY","RECENT"]},"intervalHours":{"default":6,"type":"integer","minimum":4,"maximum":24},"status":{"default":"ACTIVE","type":"string","enum":["ACTIVE","PAUSED"]},"sources":{"minItems":1,"maxItems":15,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["KEYWORD"]},"query":{"type":"string","minLength":2,"maxLength":500}},"required":["type","query"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["PROFILE_ENGAGERS"]},"username":{"type":"string"},"includeReplies":{"default":true,"type":"boolean"},"includeQuotes":{"default":true,"type":"boolean"},"includeReposts":{"default":true,"type":"boolean"}},"required":["type","username"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["FOLLOWERS"]},"username":{"type":"string"}},"required":["type","username"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["LIST_MEMBERS"]},"listId":{"type":"string","minLength":1,"maxLength":64},"listUrl":{"nullable":true,"type":"string","maxLength":2048,"format":"uri"}},"required":["type","listId"]}]}},"newListName":{"description":"A name for a new contact list to save leads to.","type":"string","minLength":1,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name","audienceDescription","sources"]},"example":{"name":"Example","audienceDescription":"<audienceDescription>","sources":[{"type":"KEYWORD","query":"build in public"}],"dryRun":true}}}}}},"/signals/find-customers":{"post":{"operationId":"signals.find_customers","summary":"Find customers for a product","description":"One-click agent that finds people asking for what a product does, and its competitors' customers. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"find_customers","x-xholic-cli":"xholic signals find-customers","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/find-customers \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals find-customers --product-id '<productId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"find_customers\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/find-customers\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/find-customers\",\n  {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/find-customers\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/find-customers\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/find-customers\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/find-customers\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":1,"maxLength":160},"replaceAgentId":{"type":"string","minLength":1,"maxLength":160},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId"]},"example":{"productId":"<productId>","dryRun":true}}}}}},"/signals/update-agent":{"post":{"operationId":"signals.update_agent","summary":"Edit a Signals agent","description":"Change a Signals agent's audience, sources, rubric or schedule. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_update_agent","x-xholic-cli":"xholic signals update-agent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/update-agent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"agentId\":\"<agentId>\",\"changes\":{},\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals update-agent --agent-id '<agentId>' --changes '{}' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_update_agent\",\n  \"arguments\": {\n    \"agentId\": \"<agentId>\",\n    \"changes\": {},\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/update-agent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"agentId\": \"<agentId>\",\n    \"changes\": {},\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/update-agent\",\n  {\n    \"agentId\": \"<agentId>\",\n    \"changes\": {},\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/update-agent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"agentId\": \"<agentId>\",\n        \"changes\": {},\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"agentId\":\"<agentId>\",\"changes\":{},\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/update-agent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/update-agent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"agentId\":\"<agentId>\",\"changes\":{},\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/update-agent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"agentId\":\"<agentId>\",\"changes\":{},\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"agentId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"changes":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"productId":{"nullable":true,"type":"string","minLength":1,"maxLength":160},"audienceDescription":{"type":"string","minLength":20,"maxLength":3000},"exclusions":{"nullable":true,"type":"string","maxLength":1500},"rubric":{"nullable":true,"type":"object","properties":{"who":{"type":"string","minLength":1,"maxLength":600},"needs":{"default":[],"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"disqualifiers":{"default":[],"maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"exampleMatch":{"default":null,"nullable":true,"type":"string","maxLength":600},"exampleNonMatch":{"default":null,"nullable":true,"type":"string","maxLength":600}},"required":["who"]},"strictness":{"type":"string","enum":["HIGH_PRECISION","DISCOVERY"]},"dmPolicy":{"type":"string","enum":["ANYONE","OPEN_DMS_ONLY"]},"baselineMode":{"type":"string","enum":["FUTURE_ONLY","RECENT"]},"intervalHours":{"type":"integer","minimum":4,"maximum":24},"sources":{"minItems":1,"maxItems":15,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["KEYWORD"]},"query":{"type":"string","minLength":2,"maxLength":500}},"required":["type","query"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["PROFILE_ENGAGERS"]},"username":{"type":"string"},"includeReplies":{"default":true,"type":"boolean"},"includeQuotes":{"default":true,"type":"boolean"},"includeReposts":{"default":true,"type":"boolean"}},"required":["type","username"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["FOLLOWERS"]},"username":{"type":"string"}},"required":["type","username"]},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":120},"type":{"type":"string","enum":["LIST_MEMBERS"]},"listId":{"type":"string","minLength":1,"maxLength":64},"listUrl":{"nullable":true,"type":"string","maxLength":2048,"format":"uri"}},"required":["type","listId"]}]},"description":"The agent's full list of sources after the change, kept ones included."},"destinationListId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"newListName":{"type":"string","minLength":1,"maxLength":80,"description":"A name for a new contact list to save leads to."}}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["agentId","changes"]},"example":{"agentId":"<agentId>","changes":{},"dryRun":true}}}}}},"/signals/set-status":{"post":{"operationId":"signals.set_status","summary":"Pause or resume a Signals agent","description":"Pause or resume a Signals agent.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_set_status","x-xholic-cli":"xholic signals set-status","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/set-status \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"agentId\":\"<agentId>\",\"status\":\"ACTIVE\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals set-status --agent-id '<agentId>' --status 'ACTIVE' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_set_status\",\n  \"arguments\": {\n    \"agentId\": \"<agentId>\",\n    \"status\": \"ACTIVE\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/set-status\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"agentId\": \"<agentId>\",\n    \"status\": \"ACTIVE\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/set-status\",\n  {\n    \"agentId\": \"<agentId>\",\n    \"status\": \"ACTIVE\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/set-status\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"agentId\": \"<agentId>\",\n        \"status\": \"ACTIVE\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"agentId\":\"<agentId>\",\"status\":\"ACTIVE\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/set-status\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/set-status\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"agentId\":\"<agentId>\",\"status\":\"ACTIVE\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/set-status\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"agentId\":\"<agentId>\",\"status\":\"ACTIVE\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"agentId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["ACTIVE","PAUSED"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["agentId","status"]},"example":{"agentId":"<agentId>","status":"ACTIVE","dryRun":true}}}}}},"/competitors/list":{"get":{"operationId":"competitors.list","summary":"Product competitors","description":"A product's competitors, optionally discovering new ones.","tags":["competitors"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"competitors_list","x-xholic-cli":"xholic competitors list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/competitors/list?productId=%3CproductId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic competitors list --product-id '<productId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"competitors_list\",\n  \"arguments\": {\n    \"productId\": \"<productId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/competitors/list?productId=%3CproductId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/competitors/list\", {\n  params: {\n    \"productId\": \"<productId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/competitors/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"productId\": \"<productId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/competitors/list?productId=%3CproductId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/competitors/list?productId=%3CproductId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/competitors/list?productId=%3CproductId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"productId","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"example":"<productId>"},{"name":"discover","in":"query","required":false,"schema":{"default":false,"description":"Search for competitors when the product has none yet.","type":"boolean"},"description":"Search for competitors when the product has none yet."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/competitors/add":{"post":{"operationId":"competitors.add","summary":"Add a competitor","description":"Add a competitor to a product. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["competitors"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"competitors_add","x-xholic-cli":"xholic competitors add","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/competitors/add \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"entry\":\"<entry>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic competitors add --product-id '<productId>' --entry '<entry>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"competitors_add\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"entry\": \"<entry>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/competitors/add\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"entry\": \"<entry>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/competitors/add\",\n  {\n    \"productId\": \"<productId>\",\n    \"entry\": \"<entry>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/competitors/add\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"entry\": \"<entry>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"entry\":\"<entry>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/competitors/add\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/competitors/add\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"entry\":\"<entry>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/competitors/add\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"entry\":\"<entry>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"entry":{"type":"string","minLength":1,"maxLength":200,"description":"An @handle, an x.com profile link or a company name."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId","entry"]},"example":{"productId":"<productId>","entry":"<entry>","dryRun":true}}}}}},"/contacts/list":{"get":{"operationId":"contacts.list","summary":"Contacts","description":"Contacts and lists: search, filter by score or intent.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_contacts","x-xholic-cli":"xholic contacts list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contacts/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_contacts\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contacts/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contacts/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contacts/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"listId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","maxLength":80}},{"name":"minimumScore","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":3}},{"name":"intent","in":"query","required":false,"schema":{"type":"string","enum":["HOT","WARM","COLD"]}},{"name":"limit","in":"query","required":false,"schema":{"default":15,"type":"integer","minimum":1,"maximum":30}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/contacts/export":{"get":{"operationId":"contacts.export","summary":"Export contacts","description":"Contacts in a list as data.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"contacts_export","x-xholic-cli":"xholic contacts export","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contacts/export' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts export"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_export\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/export\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contacts/export\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contacts/export\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contacts/export\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/export\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/export\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"listId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","maxLength":80}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/audience/dataset":{"get":{"operationId":"audience.dataset","summary":"Audience dataset","description":"Collect a post's repliers, quoters or reposters, or an X list's members, as people you can filter, research and message.","tags":["audience"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"audience_dataset","x-xholic-cli":"xholic audience dataset","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/audience/dataset?source=replies&sourceId=%3CsourceId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic audience dataset --source 'replies' --source-id '<sourceId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"audience_dataset\",\n  \"arguments\": {\n    \"source\": \"replies\",\n    \"sourceId\": \"<sourceId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/audience/dataset?source=replies&sourceId=%3CsourceId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/audience/dataset\", {\n  params: {\n    \"source\": \"replies\",\n    \"sourceId\": \"<sourceId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/audience/dataset\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"source\": \"replies\",\n        \"sourceId\": \"<sourceId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/audience/dataset?source=replies&sourceId=%3CsourceId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/audience/dataset?source=replies&sourceId=%3CsourceId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/audience/dataset?source=replies&sourceId=%3CsourceId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"source","in":"query","required":true,"schema":{"type":"string","enum":["replies","reposts","list"]},"example":"replies"},{"name":"sourceId","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{6,30}$"},"example":"<sourceId>"},{"name":"usernames","in":"query","required":false,"schema":{"maxItems":100,"type":"array","items":{"type":"string","pattern":"^[A-Za-z0-9_]{1,15}$"}}},{"name":"openDmsOnly","in":"query","required":false,"schema":{"default":false,"type":"boolean"}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/ask/start":{"post":{"operationId":"ask.start","summary":"Hand a job to Xholic","description":"Hand a long job to Xholic's own agent, e.g. 'find 30 leads, research each and draft DMs'. Uses Xholic AI credits: quote first, show it to the user, pass confirmCredits after they agree. Returns a task id; read progress with ask.task.\n\nUses Xholic AI credits (up to about 25). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"ask_xholic","x-xholic-cli":"xholic ask start","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/ask/start \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"task\":\"Summarize my last week on X\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic ask start --task 'Summarize my last week on X' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_xholic\",\n  \"arguments\": {\n    \"task\": \"Summarize my last week on X\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/start\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"task\": \"Summarize my last week on X\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/ask/start\",\n  {\n    \"task\": \"Summarize my last week on X\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/ask/start\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"task\": \"Summarize my last week on X\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"task\":\"Summarize my last week on X\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/ask/start\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/start\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"task\":\"Summarize my last week on X\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/start\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"task\":\"Summarize my last week on X\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"string","minLength":1,"maxLength":8000,"description":"The job, in the user's words."},"model":{"description":"Ask model. Defaults to sonnet. Advanced models need Max.","type":"string","enum":["luna","sol","sonnet","astra","opus","fable"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["task"]},"example":{"task":"Summarize my last week on X","dryRun":true}}}}}},"/ask/task":{"get":{"operationId":"ask.task","summary":"Ask job status","description":"Status and answer of a job started with ask_xholic or draft_with_xholic.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"ask_task","x-xholic-cli":"xholic ask task","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/ask/task?taskId=%3CtaskId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic ask task --task-id '<taskId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_task\",\n  \"arguments\": {\n    \"taskId\": \"<taskId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/task?taskId=%3CtaskId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/ask/task\", {\n  params: {\n    \"taskId\": \"<taskId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/ask/task\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"taskId\": \"<taskId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/ask/task?taskId=%3CtaskId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/task?taskId=%3CtaskId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/task?taskId=%3CtaskId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"taskId","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120},"example":"<taskId>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/drafts/with-xholic":{"post":{"operationId":"drafts.with_xholic","summary":"Write with Xholic's writer","description":"Only when the user explicitly asks for Xholic's writer. Runs Xholic's data-first Worker writer: every post starts from a real post that worked, one subject per post. Uses Xholic AI credits: quote first and pass confirmCredits after the user agrees. Returns a task; read drafts with ask.task. Otherwise write posts yourself with get_writing_kit.\n\nUses Xholic AI credits (up to about 25). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["drafts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"draft_with_xholic","x-xholic-cli":"xholic drafts with-xholic","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/drafts/with-xholic \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic drafts with-xholic --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"draft_with_xholic\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/drafts/with-xholic\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/drafts/with-xholic\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/drafts/with-xholic\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/drafts/with-xholic\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/drafts/with-xholic\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/drafts/with-xholic\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","minimum":1,"maximum":12},"angles":{"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":500}},"sourcePostIds":{"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"likePostId":{"description":"Keep this post's shape (\"like this post\").","type":"string","minLength":1,"maxLength":40},"topic":{"type":"string","maxLength":300},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}}},"example":{"dryRun":true}}}}}},"/drafts/reply-with-xholic":{"post":{"operationId":"drafts.reply_with_xholic","summary":"Reply with Xholic's reply writer","description":"Only when the user explicitly asks for Xholic's reply writer. Drafts replies to a post with Xholic's reply pipeline. Uses Xholic AI credits: quote first and pass confirmCredits after the user agrees. Otherwise write the reply yourself using get_me and get_post.\n\nUses Xholic AI credits (up to about 25). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["drafts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"draft_reply_with_xholic","x-xholic-cli":"xholic drafts reply-with-xholic","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/drafts/reply-with-xholic \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic drafts reply-with-xholic --tweet-id '<tweetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"draft_reply_with_xholic\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/drafts/reply-with-xholic\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/drafts/reply-with-xholic\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/drafts/reply-with-xholic\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/drafts/reply-with-xholic\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/drafts/reply-with-xholic\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/drafts/reply-with-xholic\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","minLength":1,"maxLength":40},"instructions":{"type":"string","maxLength":1000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["tweetId"]},"example":{"tweetId":"<tweetId>","dryRun":true}}}}}},"/actions/find":{"get":{"operationId":"actions.find","summary":"Find an action","description":"Search everything Xholic can do (about 150 actions) and the docs. Use it when no loaded tool fits; then call run_read_action or run_write_action with the action id.","tags":["actions"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"find_actions","x-xholic-cli":"xholic actions find","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/actions/find?query=build+in+public' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic actions find --query 'build in public'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"find_actions\",\n  \"arguments\": {\n    \"query\": \"build in public\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/actions/find?query=build+in+public\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/actions/find\", {\n  params: {\n    \"query\": \"build in public\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/actions/find\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"query\": \"build in public\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/actions/find?query=build+in+public\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/actions/find?query=build+in+public\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/actions/find?query=build+in+public\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200},"example":"build in public"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":25}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/docs/read":{"get":{"operationId":"docs.read","summary":"Read a docs page","description":"Read a page of the Xholic docs by path, e.g. /api/authentication.","tags":["docs"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"read_doc","x-xholic-cli":"xholic docs read","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/docs/read?path=%3Cpath%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic docs read --path '<path>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"read_doc\",\n  \"arguments\": {\n    \"path\": \"<path>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/docs/read?path=%3Cpath%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/docs/read\", {\n  params: {\n    \"path\": \"<path>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/docs/read\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"path\": \"<path>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/docs/read?path=%3Cpath%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/docs/read?path=%3Cpath%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/docs/read?path=%3Cpath%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200},"example":"<path>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/notes/add":{"post":{"operationId":"notes.add","summary":"Save a note","description":"Save a note to the account's Xholic memory: something to post later (\"something like this Thursday\"), a plan, a test to run (\"try 4 threads vs 4 single posts\"), a finding, or work another agent finished that is worth posting about. Xholic adds the numbers of any linked posts, turns a due or triggered note into drafts the user approves, and writes the result back once a post made from it settles. Save only what the user asked for or clearly intends; never notes \"just in case\". Not for lasting facts or preferences about the user: use remember for those.","tags":["notes"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"add_note","x-xholic-cli":"xholic notes add","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/notes/add \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"title\":\"<title>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic notes add --title '<title>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"add_note\",\n  \"arguments\": {\n    \"title\": \"<title>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/notes/add\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"title\": \"<title>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/notes/add\",\n  {\n    \"title\": \"<title>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/notes/add\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"title\": \"<title>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"title\":\"<title>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/notes/add\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/notes/add\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"title\":\"<title>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/notes/add\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"title\":\"<title>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":140,"description":"One line: what to do or what was found."},"body":{"description":"Details, the user's words, the analysis.","type":"string","maxLength":4000},"kind":{"description":"IDEA (default), PLAN, TEST, FINDING or HANDOFF.","type":"string","enum":["IDEA","PLAN","TEST","FINDING","HANDOFF"]},"due":{"description":"When to act: a date such as 2026-10-30, a local date and time such as 2026-10-30T09:00 (then pass timezone), or an ISO time with offset.","type":"string","minLength":1,"maxLength":40},"timezone":{"description":"IANA timezone for due, such as Asia/Kolkata.","type":"string","minLength":1,"maxLength":80},"trigger":{"description":"Fire on an event instead of a date: OWN_SPIKE (the account's next follower spike or breakout post; for posts that need a real number), MILESTONE (followers or posts crossing a number; the next round follower count when left out), TRACKED_POSTS (one of these accounts posts, optionally about a topic), TOPIC_HEATS (the topic shows up in the account's trends).","oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["OWN_SPIKE"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["MILESTONE"]},"followers":{"type":"integer","exclusiveMinimum":true,"maximum":9007199254740991},"posts":{"type":"integer","exclusiveMinimum":true,"maximum":9007199254740991}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["TRACKED_POSTS"]},"handles":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","pattern":"^@?[A-Za-z0-9_]{1,15}$"}},"topic":{"type":"string","minLength":2,"maxLength":120}},"required":["type","handles"]},{"type":"object","properties":{"type":{"type":"string","enum":["TOPIC_HEATS"]},"topic":{"type":"string","minLength":2,"maxLength":120}},"required":["type","topic"]}]},"posts":{"description":"X post URLs or ids the note is about. Xholic adds their numbers and why they worked.","maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}},"handles":{"description":"X accounts the note is about.","maxItems":20,"type":"array","items":{"type":"string","pattern":"^@?[A-Za-z0-9_]{1,15}$"}},"format":{"type":"string","enum":["relatable_scene","one_liner","contrast_pair","hot_take","contrarian_reframe","personal_story","proof_numbers","build_update","list_playbook","framework","question","observation","trend_reaction","ironic_humor","advice","motivation","networking","promotion","other"],"description":"The post format, such as question, one_liner, proof_numbers or list_playbook."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["title"]},"example":{"title":"<title>","dryRun":true}}}}}},"/notes/find":{"get":{"operationId":"notes.find","summary":"Notes","description":"Search the account's notes: what's coming up, ideas from saved posts, tests, findings and their results. Search by words, status, format or a post. Each note has its id, where it came from and any result; link to the note when you use it so the user sees why.","tags":["notes"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"find_notes","x-xholic-cli":"xholic notes find","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/notes/find' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic notes find"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"find_notes\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/notes/find\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/notes/find\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/notes/find\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/notes/find\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/notes/find\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/notes/find\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"query","in":"query","required":false,"schema":{"description":"Words to look for in the title or body.","type":"string","maxLength":200},"description":"Words to look for in the title or body."},{"name":"status","in":"query","required":false,"schema":{"description":"OPEN (coming up, default), DONE, STALE or DROPPED.","type":"string","enum":["OPEN","DONE","STALE","DROPPED"]},"description":"OPEN (coming up, default), DONE, STALE or DROPPED."},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["relatable_scene","one_liner","contrast_pair","hot_take","contrarian_reframe","personal_story","proof_numbers","build_update","list_playbook","framework","question","observation","trend_reaction","ironic_humor","advice","motivation","networking","promotion","other"],"description":"The post format, such as question, one_liner, proof_numbers or list_playbook."},"description":"The post format, such as question, one_liner, proof_numbers or list_playbook."},{"name":"post","in":"query","required":false,"schema":{"description":"An X post URL or id the note refers to.","type":"string","maxLength":2048},"description":"An X post URL or id the note refers to."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":200}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/notes/update":{"post":{"operationId":"notes.update","summary":"Update a note","description":"Change a note's text, due date or trigger, or mark it DONE or DROPPED when the user says it is finished or no longer wanted.","tags":["notes"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"update_note","x-xholic-cli":"xholic notes update","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/notes/update \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"noteId\":\"<noteId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic notes update --note-id '<noteId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"update_note\",\n  \"arguments\": {\n    \"noteId\": \"<noteId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/notes/update\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"noteId\": \"<noteId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/notes/update\",\n  {\n    \"noteId\": \"<noteId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/notes/update\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"noteId\": \"<noteId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"noteId\":\"<noteId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/notes/update\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/notes/update\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"noteId\":\"<noteId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/notes/update\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"noteId\":\"<noteId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"noteId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The note id from add_note or find_notes."},"title":{"type":"string","minLength":1,"maxLength":140},"body":{"type":"string","maxLength":4000},"due":{"nullable":true,"description":"When to act: a date such as 2026-10-30, a local date and time such as 2026-10-30T09:00 (then pass timezone), or an ISO time with offset.","type":"string","minLength":1,"maxLength":40},"timezone":{"description":"IANA timezone for due, such as Asia/Kolkata.","type":"string","minLength":1,"maxLength":80},"trigger":{"nullable":true,"description":"Fire on an event instead of a date: OWN_SPIKE (the account's next follower spike or breakout post; for posts that need a real number), MILESTONE (followers or posts crossing a number; the next round follower count when left out), TRACKED_POSTS (one of these accounts posts, optionally about a topic), TOPIC_HEATS (the topic shows up in the account's trends).","oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["OWN_SPIKE"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["MILESTONE"]},"followers":{"type":"integer","exclusiveMinimum":true,"maximum":9007199254740991},"posts":{"type":"integer","exclusiveMinimum":true,"maximum":9007199254740991}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["TRACKED_POSTS"]},"handles":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","pattern":"^@?[A-Za-z0-9_]{1,15}$"}},"topic":{"type":"string","minLength":2,"maxLength":120}},"required":["type","handles"]},{"type":"object","properties":{"type":{"type":"string","enum":["TOPIC_HEATS"]},"topic":{"type":"string","minLength":2,"maxLength":120}},"required":["type","topic"]}]},"status":{"type":"string","enum":["OPEN","DONE","DROPPED"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["noteId"]},"example":{"noteId":"<noteId>","dryRun":true}}}}}},"/notes/delete":{"post":{"operationId":"notes.delete","summary":"Delete a note","description":"Delete a note for good. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["notes"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"delete_note","x-xholic-cli":"xholic notes delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/notes/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"noteId\":\"<noteId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic notes delete --note-id '<noteId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"delete_note\",\n  \"arguments\": {\n    \"noteId\": \"<noteId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/notes/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"noteId\": \"<noteId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/notes/delete\",\n  {\n    \"noteId\": \"<noteId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/notes/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"noteId\": \"<noteId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"noteId\":\"<noteId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/notes/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/notes/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"noteId\":\"<noteId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/notes/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"noteId\":\"<noteId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"noteId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The note id from add_note or find_notes."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["noteId"]},"example":{"noteId":"<noteId>","dryRun":true}}}}}},"/lessons/list":{"get":{"operationId":"lessons.list","summary":"What works for me","description":"What has worked on X for this account, by post format, judged against its own normal: each lesson's strength (being tested, early sign, seems to work, works consistently), its tries and evidence posts. Niche lessons come from similar accounts until the account has its own. Use them as evidence when choosing a format; never as rules.","tags":["lessons"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"whats_worked_for_me","x-xholic-cli":"xholic lessons list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/lessons/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic lessons list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"whats_worked_for_me\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/lessons/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/lessons/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/lessons/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/lessons/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/lessons/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/lessons/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/lessons/feedback":{"post":{"operationId":"lessons.feedback","summary":"Rate a lesson","description":"Record the user's answer on a lesson: CONFIRMED (\"that's right\") or REJECTED (\"that's wrong\"; Xholic stops using it). Only with the user's own answer.","tags":["lessons"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"rate_lesson","x-xholic-cli":"xholic lessons feedback","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/lessons/feedback \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"lessonId\":\"<lessonId>\",\"verdict\":\"CONFIRMED\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic lessons feedback --lesson-id '<lessonId>' --verdict 'CONFIRMED' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"rate_lesson\",\n  \"arguments\": {\n    \"lessonId\": \"<lessonId>\",\n    \"verdict\": \"CONFIRMED\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/lessons/feedback\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"lessonId\": \"<lessonId>\",\n    \"verdict\": \"CONFIRMED\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/lessons/feedback\",\n  {\n    \"lessonId\": \"<lessonId>\",\n    \"verdict\": \"CONFIRMED\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/lessons/feedback\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"lessonId\": \"<lessonId>\",\n        \"verdict\": \"CONFIRMED\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"lessonId\":\"<lessonId>\",\"verdict\":\"CONFIRMED\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/lessons/feedback\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/lessons/feedback\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"lessonId\":\"<lessonId>\",\"verdict\":\"CONFIRMED\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/lessons/feedback\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"lessonId\":\"<lessonId>\",\"verdict\":\"CONFIRMED\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lessonId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The lesson id from whats_worked_for_me."},"verdict":{"type":"string","enum":["CONFIRMED","REJECTED"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["lessonId","verdict"]},"example":{"lessonId":"<lessonId>","verdict":"CONFIRMED","dryRun":true}}}}}},"/scheduler/get-settings":{"get":{"operationId":"scheduler.get_settings","summary":"Scheduler settings","description":"The account's scheduler settings: timezone, posting window, quote fallback and default post automations with saved templates.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"scheduler_get_settings","x-xholic-cli":"xholic scheduler get-settings","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/get-settings' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler get-settings"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_get_settings\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/get-settings\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/get-settings\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/get-settings\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/get-settings\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/get-settings\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/get-settings\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/update-settings":{"post":{"operationId":"scheduler.update_settings","summary":"Update scheduler settings","description":"Replace the scheduler timezone and default post automations (with templates). Read scheduler.get_settings first and send the whole automation object back with your changes. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"scheduler_update_settings","x-xholic-cli":"xholic scheduler update-settings","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/scheduler/update-settings \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"timezone\":\"America/New_York\",\"automation\":{},\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler update-settings --timezone 'America/New_York' --automation '{}' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_update_settings\",\n  \"arguments\": {\n    \"timezone\": \"America/New_York\",\n    \"automation\": {},\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/update-settings\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"timezone\": \"America/New_York\",\n    \"automation\": {},\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/scheduler/update-settings\",\n  {\n    \"timezone\": \"America/New_York\",\n    \"automation\": {},\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/scheduler/update-settings\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"timezone\": \"America/New_York\",\n        \"automation\": {},\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"timezone\":\"America/New_York\",\"automation\":{},\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/scheduler/update-settings\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/update-settings\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"timezone\":\"America/New_York\",\"automation\":{},\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/update-settings\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"timezone\":\"America/New_York\",\"automation\":{},\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"automation":{"type":"object","properties":{},"additionalProperties":{},"description":"The full default automation settings as returned by scheduler.get_settings, including templates."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["timezone","automation"]},"example":{"timezone":"America/New_York","automation":{},"dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/scheduler/set-posting-window":{"post":{"operationId":"scheduler.set_posting_window","summary":"Set the posting window","description":"Set the hours of the day posts may go out at, or clear it with null. Next-slot and best-time scheduling stay inside it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"scheduler_set_posting_window","x-xholic-cli":"xholic scheduler set-posting-window","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/scheduler/set-posting-window \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"timezone\":\"America/New_York\",\"postingWindow\":{\"startMinutes\":1,\"endMinutes\":1},\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler set-posting-window --timezone 'America/New_York' --posting-window '{\"startMinutes\":1,\"endMinutes\":1}' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_set_posting_window\",\n  \"arguments\": {\n    \"timezone\": \"America/New_York\",\n    \"postingWindow\": {\n      \"startMinutes\": 1,\n      \"endMinutes\": 1\n    },\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/set-posting-window\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"timezone\": \"America/New_York\",\n    \"postingWindow\": {\n      \"startMinutes\": 1,\n      \"endMinutes\": 1\n    },\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/scheduler/set-posting-window\",\n  {\n    \"timezone\": \"America/New_York\",\n    \"postingWindow\": {\n      \"startMinutes\": 1,\n      \"endMinutes\": 1\n    },\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/scheduler/set-posting-window\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"timezone\": \"America/New_York\",\n        \"postingWindow\": {\n            \"startMinutes\": 1,\n            \"endMinutes\": 1\n        },\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"timezone\":\"America/New_York\",\"postingWindow\":{\"startMinutes\":1,\"endMinutes\":1},\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/scheduler/set-posting-window\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/set-posting-window\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"timezone\":\"America/New_York\",\"postingWindow\":{\"startMinutes\":1,\"endMinutes\":1},\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/set-posting-window\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"timezone\":\"America/New_York\",\"postingWindow\":{\"startMinutes\":1,\"endMinutes\":1},\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"postingWindow":{"nullable":true,"type":"object","properties":{"startMinutes":{"type":"integer","minimum":0,"maximum":1439,"description":"Minutes after local midnight, e.g. 540 for 9:00."},"endMinutes":{"type":"integer","minimum":0,"maximum":1439,"description":"Minutes after local midnight; must differ from start."}},"required":["startMinutes","endMinutes"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["timezone","postingWindow"]},"example":{"timezone":"America/New_York","postingWindow":{"startMinutes":1,"endMinutes":1},"dryRun":true}}}}}},"/scheduler/set-quote-fallback":{"post":{"operationId":"scheduler.set_quote_fallback","summary":"Set the quote fallback","description":"Choose what happens when a scheduled quote post's original is gone at publish time: post without the quote, or fail the post. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"scheduler_set_quote_fallback","x-xholic-cli":"xholic scheduler set-quote-fallback","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/scheduler/set-quote-fallback \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"timezone\":\"America/New_York\",\"quoteUnavailableAction\":\"SEND_WITHOUT_QUOTE\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler set-quote-fallback --timezone 'America/New_York' --quote-unavailable-action 'SEND_WITHOUT_QUOTE' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_set_quote_fallback\",\n  \"arguments\": {\n    \"timezone\": \"America/New_York\",\n    \"quoteUnavailableAction\": \"SEND_WITHOUT_QUOTE\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/set-quote-fallback\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"timezone\": \"America/New_York\",\n    \"quoteUnavailableAction\": \"SEND_WITHOUT_QUOTE\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/scheduler/set-quote-fallback\",\n  {\n    \"timezone\": \"America/New_York\",\n    \"quoteUnavailableAction\": \"SEND_WITHOUT_QUOTE\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/scheduler/set-quote-fallback\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"timezone\": \"America/New_York\",\n        \"quoteUnavailableAction\": \"SEND_WITHOUT_QUOTE\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"timezone\":\"America/New_York\",\"quoteUnavailableAction\":\"SEND_WITHOUT_QUOTE\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/scheduler/set-quote-fallback\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/set-quote-fallback\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"timezone\":\"America/New_York\",\"quoteUnavailableAction\":\"SEND_WITHOUT_QUOTE\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/set-quote-fallback\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"timezone\":\"America/New_York\",\"quoteUnavailableAction\":\"SEND_WITHOUT_QUOTE\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"quoteUnavailableAction":{"type":"string","enum":["SEND_WITHOUT_QUOTE","FAIL_POST"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["timezone","quoteUnavailableAction"]},"example":{"timezone":"America/New_York","quoteUnavailableAction":"SEND_WITHOUT_QUOTE","dryRun":true}}}}}},"/scheduler/lookup-quote":{"get":{"operationId":"scheduler.lookup_quote","summary":"Look up a post to quote","description":"Preview the X post behind a URL before quoting it: author, text, time and media.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"scheduler_lookup_quote","x-xholic-cli":"xholic scheduler lookup-quote","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/lookup-quote?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler lookup-quote --url 'https://example.com/hooks/xholic'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_lookup_quote\",\n  \"arguments\": {\n    \"url\": \"https://example.com/hooks/xholic\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/lookup-quote?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/lookup-quote\", {\n  params: {\n    \"url\": \"https://example.com/hooks/xholic\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/lookup-quote\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"url\": \"https://example.com/hooks/xholic\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/lookup-quote?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/lookup-quote?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/lookup-quote?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":2048,"description":"The X post URL."},"example":"https://example.com/hooks/xholic","description":"The X post URL."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/parse-time":{"get":{"operationId":"scheduler.parse_time","summary":"Parse a schedule time","description":"Turn words like \"tomorrow 9am\" or \"next friday at noon\" into an exact ISO time in the account's timezone. Changes nothing.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"scheduler_parse_time","x-xholic-cli":"xholic scheduler parse-time","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/parse-time?input=%3Cinput%3E&timezone=America%2FNew_York' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler parse-time --input '<input>' --timezone 'America/New_York'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_parse_time\",\n  \"arguments\": {\n    \"input\": \"<input>\",\n    \"timezone\": \"America/New_York\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/parse-time?input=%3Cinput%3E&timezone=America%2FNew_York\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/parse-time\", {\n  params: {\n    \"input\": \"<input>\",\n    \"timezone\": \"America/New_York\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/parse-time\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"input\": \"<input>\",\n        \"timezone\": \"America/New_York\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/parse-time?input=%3Cinput%3E&timezone=America%2FNew_York\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/parse-time?input=%3Cinput%3E&timezone=America%2FNew_York\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/parse-time?input=%3Cinput%3E&timezone=America%2FNew_York\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"input","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200},"example":"<input>"},{"name":"timezone","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"example":"America/New_York","description":"IANA timezone such as America/New_York. Use the user's timezone."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/schedule-view":{"get":{"operationId":"scheduler.schedule_view","summary":"Calendar view","description":"The posting calendar day by day: scheduled posts, open slots and best times, for up to 42 days.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"scheduler_schedule_view","x-xholic-cli":"xholic scheduler schedule-view","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/schedule-view' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler schedule-view"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_schedule_view\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/schedule-view\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/schedule-view\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/schedule-view\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/schedule-view\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/schedule-view\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/schedule-view\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"tagIds","in":"query","required":false,"schema":{"description":"Comma-separated tag ids from list_tags, to show only posts with those tags.","type":"string","maxLength":1900},"description":"Comma-separated tag ids from list_tags, to show only posts with those tags."},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"description":"IANA timezone such as America/New_York. Use the user's timezone."},{"name":"days","in":"query","required":false,"schema":{"description":"Days to show (default 21).","type":"integer","minimum":1,"maximum":42},"description":"Days to show (default 21)."},{"name":"startDate","in":"query","required":false,"schema":{"description":"First day, YYYY-MM-DD. Defaults to today.","type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"description":"First day, YYYY-MM-DD. Defaults to today."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/dashboard-summary":{"get":{"operationId":"scheduler.dashboard_summary","summary":"Scheduler summary","description":"What needs attention in the scheduler: failed posts, failed automations and what's coming up next.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"scheduler_dashboard_summary","x-xholic-cli":"xholic scheduler dashboard-summary","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/dashboard-summary' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler dashboard-summary"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_dashboard_summary\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/dashboard-summary\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/dashboard-summary\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/dashboard-summary\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/dashboard-summary\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/dashboard-summary\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/dashboard-summary\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/acknowledge-alert":{"post":{"operationId":"scheduler.acknowledge_alert","summary":"Dismiss a scheduler alert","description":"Mark a failed post or failed automation alert from scheduler.dashboard_summary as seen so it stops showing.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"scheduler_acknowledge_alert","x-xholic-cli":"xholic scheduler acknowledge-alert","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/scheduler/acknowledge-alert \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"kind\":\"POST\",\"postId\":\"<postId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler acknowledge-alert --kind 'POST' --post-id '<postId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_acknowledge_alert\",\n  \"arguments\": {\n    \"kind\": \"POST\",\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/acknowledge-alert\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"kind\": \"POST\",\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/scheduler/acknowledge-alert\",\n  {\n    \"kind\": \"POST\",\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/scheduler/acknowledge-alert\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"kind\": \"POST\",\n        \"postId\": \"<postId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"kind\":\"POST\",\"postId\":\"<postId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/scheduler/acknowledge-alert\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/acknowledge-alert\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"kind\":\"POST\",\"postId\":\"<postId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/acknowledge-alert\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"kind\":\"POST\",\"postId\":\"<postId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["POST","AUTOMATION"]},"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"ruleId":{"description":"Required when kind is AUTOMATION.","type":"string","minLength":1,"maxLength":120},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["kind","postId"]},"example":{"kind":"POST","postId":"<postId>","dryRun":true}}}}}},"/scheduler/best-times":{"get":{"operationId":"scheduler.best_times","summary":"Best times to post","description":"The best upcoming times for this account to post, from when its audience engages. Use before scheduling when the user wants a good time rather than a set one.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"best_posting_times","x-xholic-cli":"xholic scheduler best-times","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/best-times' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler best-times"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"best_posting_times\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/best-times\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/best-times\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/best-times\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/best-times\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/best-times\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/best-times\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"timezone","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"description":"IANA timezone such as America/New_York. Use the user's timezone."},{"name":"slotCount","in":"query","required":false,"schema":{"description":"How many times to return (default 12).","type":"integer","minimum":1,"maximum":140},"description":"How many times to return (default 12)."},{"name":"windowStartMinutes","in":"query","required":false,"schema":{"description":"Only times after this, in minutes after local midnight. Send with windowEndMinutes.","type":"integer","minimum":0,"maximum":1439},"description":"Only times after this, in minutes after local midnight. Send with windowEndMinutes."},{"name":"windowEndMinutes","in":"query","required":false,"schema":{"description":"Only times before this, in minutes after local midnight. Send with windowStartMinutes.","type":"integer","minimum":0,"maximum":1439},"description":"Only times before this, in minutes after local midnight. Send with windowStartMinutes."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/list-slots":{"get":{"operationId":"scheduler.list_slots","summary":"Weekly posting slots","description":"The account's weekly posting slots that \"next slot\" scheduling fills.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"scheduler_list_slots","x-xholic-cli":"xholic scheduler list-slots","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/scheduler/list-slots' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler list-slots"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_list_slots\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/list-slots\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/scheduler/list-slots\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/scheduler/list-slots\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/scheduler/list-slots\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/list-slots\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/list-slots\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/scheduler/replace-slots":{"post":{"operationId":"scheduler.replace_slots","summary":"Replace weekly posting slots","description":"Replace every weekly posting slot with this list. Slots left out are removed, so read scheduler.list_slots first. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["scheduler"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"scheduler_replace_slots","x-xholic-cli":"xholic scheduler replace-slots","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/scheduler/replace-slots \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"slots\":[{\"weekday\":1,\"timeOfDayMinutes\":1,\"timezone\":\"America/New_York\"}],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic scheduler replace-slots --slots '[{\"weekday\":1,\"timeOfDayMinutes\":1,\"timezone\":\"America/New_York\"}]' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"scheduler_replace_slots\",\n  \"arguments\": {\n    \"slots\": [\n      {\n        \"weekday\": 1,\n        \"timeOfDayMinutes\": 1,\n        \"timezone\": \"America/New_York\"\n      }\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/scheduler/replace-slots\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"slots\": [\n      {\n        \"weekday\": 1,\n        \"timeOfDayMinutes\": 1,\n        \"timezone\": \"America/New_York\"\n      }\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/scheduler/replace-slots\",\n  {\n    \"slots\": [\n      {\n        \"weekday\": 1,\n        \"timeOfDayMinutes\": 1,\n        \"timezone\": \"America/New_York\"\n      }\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/scheduler/replace-slots\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"slots\": [\n            {\n                \"weekday\": 1,\n                \"timeOfDayMinutes\": 1,\n                \"timezone\": \"America/New_York\"\n            }\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"slots\":[{\"weekday\":1,\"timeOfDayMinutes\":1,\"timezone\":\"America/New_York\"}],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/scheduler/replace-slots\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/scheduler/replace-slots\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"slots\":[{\"weekday\":1,\"timeOfDayMinutes\":1,\"timezone\":\"America/New_York\"}],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/scheduler/replace-slots\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"slots\":[{\"weekday\":1,\"timeOfDayMinutes\":1,\"timezone\":\"America/New_York\"}],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slots":{"maxItems":140,"type":"array","items":{"type":"object","properties":{"weekday":{"type":"integer","minimum":0,"maximum":6,"description":"0 is Sunday."},"timeOfDayMinutes":{"type":"integer","minimum":0,"maximum":1439,"description":"Minutes after local midnight."},"timezone":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"isEnabled":{"type":"boolean"}},"required":["weekday","timeOfDayMinutes","timezone"]}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["slots"]},"example":{"slots":[{"weekday":1,"timeOfDayMinutes":1,"timezone":"America/New_York"}],"dryRun":true}}}}}},"/tags/list":{"get":{"operationId":"tags.list","summary":"List tags","description":"The account's post tags (name, color, id). Use the ids to filter the queue or calendar, or to tag a post.","tags":["tags"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"list_tags","x-xholic-cli":"xholic tags list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/tags/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic tags list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"list_tags\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/tags/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/tags/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/tags/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/tags/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/tags/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/tags/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/tags/create":{"post":{"operationId":"tags.create","summary":"Create a tag","description":"Create a post tag. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["tags"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"tags_create","x-xholic-cli":"xholic tags create","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/tags/create \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic tags create --name 'Example' --color 'neutral' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"tags_create\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"color\": \"neutral\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/tags/create\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"color\": \"neutral\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/tags/create\",\n  {\n    \"name\": \"Example\",\n    \"color\": \"neutral\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/tags/create\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"color\": \"neutral\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/tags/create\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/tags/create\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/tags/create\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40},"color":{"type":"string","enum":["neutral","red","orange","amber","lime","emerald","teal","cyan","blue","indigo","violet","fuchsia"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name","color"]},"example":{"name":"Example","color":"neutral","dryRun":true}}}}}},"/tags/import-starter":{"post":{"operationId":"tags.import_starter","summary":"Add the starter tags","description":"Add Xholic's starter tag set (missing ones only). Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["tags"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"tags_import_starter","x-xholic-cli":"xholic tags import-starter","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/tags/import-starter \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic tags import-starter --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"tags_import_starter\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/tags/import-starter\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/tags/import-starter\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/tags/import-starter\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/tags/import-starter\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/tags/import-starter\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/tags/import-starter\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/tags/update":{"post":{"operationId":"tags.update","summary":"Edit a tag","description":"Rename a tag or change its color. Send both name and color. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["tags"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"tags_update","x-xholic-cli":"xholic tags update","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/tags/update \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tagId\":\"<tagId>\",\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic tags update --tag-id '<tagId>' --name 'Example' --color 'neutral' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"tags_update\",\n  \"arguments\": {\n    \"tagId\": \"<tagId>\",\n    \"name\": \"Example\",\n    \"color\": \"neutral\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/tags/update\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tagId\": \"<tagId>\",\n    \"name\": \"Example\",\n    \"color\": \"neutral\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/tags/update\",\n  {\n    \"tagId\": \"<tagId>\",\n    \"name\": \"Example\",\n    \"color\": \"neutral\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/tags/update\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tagId\": \"<tagId>\",\n        \"name\": \"Example\",\n        \"color\": \"neutral\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tagId\":\"<tagId>\",\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/tags/update\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/tags/update\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tagId\":\"<tagId>\",\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/tags/update\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tagId\":\"<tagId>\",\"name\":\"Example\",\"color\":\"neutral\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tagId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","minLength":1,"maxLength":40},"color":{"type":"string","enum":["neutral","red","orange","amber","lime","emerald","teal","cyan","blue","indigo","violet","fuchsia"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tagId","name","color"]},"example":{"tagId":"<tagId>","name":"Example","color":"neutral","dryRun":true}}}}}},"/tags/delete":{"post":{"operationId":"tags.delete","summary":"Delete a tag","description":"Delete a tag. Posts keep their text; they just lose the tag. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["tags"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"tags_delete","x-xholic-cli":"xholic tags delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/tags/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tagId\":\"<tagId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic tags delete --tag-id '<tagId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"tags_delete\",\n  \"arguments\": {\n    \"tagId\": \"<tagId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/tags/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tagId\": \"<tagId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/tags/delete\",\n  {\n    \"tagId\": \"<tagId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/tags/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tagId\": \"<tagId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tagId\":\"<tagId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/tags/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/tags/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tagId\":\"<tagId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/tags/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tagId\":\"<tagId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tagId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tagId"]},"example":{"tagId":"<tagId>","dryRun":true}}}}}},"/media/get":{"get":{"operationId":"media.get","summary":"Media status","description":"One uploaded media item's state. Poll it while a video is still processing.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"media_get","x-xholic-cli":"xholic media get","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/media/get?mediaId=%3CmediaId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic media get --media-id '<mediaId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"media_get\",\n  \"arguments\": {\n    \"mediaId\": \"<mediaId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/get?mediaId=%3CmediaId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/media/get\", {\n  params: {\n    \"mediaId\": \"<mediaId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/media/get\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"mediaId\": \"<mediaId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/media/get?mediaId=%3CmediaId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/get?mediaId=%3CmediaId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/get?mediaId=%3CmediaId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"mediaId","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"example":"<mediaId>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/media/preview":{"get":{"operationId":"media.preview","summary":"Media preview link","description":"A short-lived URL to view an uploaded media item.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"media_preview","x-xholic-cli":"xholic media preview","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/media/preview?mediaId=%3CmediaId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic media preview --media-id '<mediaId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"media_preview\",\n  \"arguments\": {\n    \"mediaId\": \"<mediaId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/preview?mediaId=%3CmediaId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/media/preview\", {\n  params: {\n    \"mediaId\": \"<mediaId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/media/preview\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"mediaId\": \"<mediaId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/media/preview?mediaId=%3CmediaId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/preview?mediaId=%3CmediaId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/preview?mediaId=%3CmediaId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"mediaId","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"example":"<mediaId>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/media/delete":{"post":{"operationId":"media.delete","summary":"Delete uploaded media","description":"Delete an uploaded media item that no post uses. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"media_delete","x-xholic-cli":"xholic media delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/media/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"mediaId\":\"<mediaId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic media delete --media-id '<mediaId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"media_delete\",\n  \"arguments\": {\n    \"mediaId\": \"<mediaId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"mediaId\": \"<mediaId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/media/delete\",\n  {\n    \"mediaId\": \"<mediaId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/media/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"mediaId\": \"<mediaId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"mediaId\":\"<mediaId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/media/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"mediaId\":\"<mediaId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"mediaId\":\"<mediaId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mediaId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["mediaId"]},"example":{"mediaId":"<mediaId>","dryRun":true}}}}}},"/media/browse-klipy":{"get":{"operationId":"media.browse_klipy","summary":"Find a GIF or meme","description":"Search or browse KLIPY GIFs and memes to attach to a post. Import a pick with media.import_klipy to get a mediaId.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"media_browse_klipy","x-xholic-cli":"xholic media browse-klipy","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/media/browse-klipy?type=gifs' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic media browse-klipy --type 'gifs'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"media_browse_klipy\",\n  \"arguments\": {\n    \"type\": \"gifs\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/browse-klipy?type=gifs\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/media/browse-klipy\", {\n  params: {\n    \"type\": \"gifs\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/media/browse-klipy\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"type\": \"gifs\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/media/browse-klipy?type=gifs\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/browse-klipy?type=gifs\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/browse-klipy?type=gifs\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","enum":["gifs","memes"]},"example":"gifs"},{"name":"q","in":"query","required":false,"schema":{"description":"Search words. Leave out for trending.","type":"string","maxLength":100},"description":"Search words. Leave out for trending."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/media/import-klipy":{"post":{"operationId":"media.import_klipy","summary":"Import a GIF or meme","description":"Copy a KLIPY GIF or meme into the account's media. Returns a mediaId to attach to a post.","tags":["media"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"media_import_klipy","x-xholic-cli":"xholic media import-klipy","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/media/import-klipy \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic media import-klipy --type 'gifs' --slug '<slug>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"media_import_klipy\",\n  \"arguments\": {\n    \"type\": \"gifs\",\n    \"slug\": \"<slug>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/media/import-klipy\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"type\": \"gifs\",\n    \"slug\": \"<slug>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/media/import-klipy\",\n  {\n    \"type\": \"gifs\",\n    \"slug\": \"<slug>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/media/import-klipy\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"type\": \"gifs\",\n        \"slug\": \"<slug>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/media/import-klipy\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/media/import-klipy\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/media/import-klipy\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["gifs","memes"]},"slug":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z0-9_-]+$","description":"The item's slug from media.browse_klipy."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["type","slug"]},"example":{"type":"gifs","slug":"<slug>","dryRun":true}}}}}},"/queue/counts":{"get":{"operationId":"queue.counts","summary":"Queue counts","description":"How many posts are queued, drafted, posted and failed.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"queue_counts","x-xholic-cli":"xholic queue counts","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/queue/counts' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic queue counts"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_counts\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/counts\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/queue/counts\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/queue/counts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/queue/counts\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/counts\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/counts\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/queue/get-post":{"get":{"operationId":"queue.get_post","summary":"Get a queued post","description":"One draft, scheduled, posted or failed post in Xholic with its text, thread, media, automations and status.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"queue_get_post","x-xholic-cli":"xholic queue get-post","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/queue/get-post?postId=%3CpostId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic queue get-post --post-id '<postId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_get_post\",\n  \"arguments\": {\n    \"postId\": \"<postId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/get-post?postId=%3CpostId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/queue/get-post\", {\n  params: {\n    \"postId\": \"<postId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/queue/get-post\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"postId\": \"<postId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/queue/get-post?postId=%3CpostId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/get-post?postId=%3CpostId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/get-post?postId=%3CpostId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"postId","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"example":"<postId>","description":"Xholic scheduled post id, from get_queue."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/queue/post-now":{"post":{"operationId":"queue.post_now","summary":"Post a queued post now","description":"Publish an existing draft or scheduled post to X right away. Send its text (the current text from queue.get_post, or the edited one). Call it only when the user asked for this in the conversation; never on your own initiative. Spends a post credit.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"queue_post_now","x-xholic-cli":"xholic queue post-now","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/post-now \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue post-now --post-id '<postId>' --text 'Shipping the API today' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_post_now\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/post-now\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/post-now\",\n  {\n    \"postId\": \"<postId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/post-now\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"text\": \"Shipping the API today\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/post-now\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/post-now\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/post-now\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"text":{"type":"string","minLength":1,"maxLength":100000},"threadParts":{"description":"For a thread: every part in order, starting with the same first post as text.","maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100000}},"media":{"description":"Media by mediaId, placed by thread part and position (0-3).","maxItems":400,"type":"array","items":{"type":"object","properties":{"mediaId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"threadPartIndex":{"type":"integer","minimum":0,"maximum":99},"position":{"type":"integer","minimum":0,"maximum":3},"altText":{"type":"string","maxLength":1000}},"required":["mediaId","threadPartIndex","position"]}},"automation":{"description":"Post automations (auto-repost, auto-plug reply, auto-delete, auto-DM). Shape as in the docs: docs.xholic.ai/api/automations.","type":"object","properties":{},"additionalProperties":{}},"expectedUpdatedAt":{"description":"The post's updatedAt from queue.get_post; refuses if it changed since.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId","text"]},"example":{"postId":"<postId>","text":"Shipping the API today","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/queue/cancel":{"post":{"operationId":"queue.cancel","summary":"Cancel a post","description":"Cancel a draft, scheduled or failed post so it never goes out. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"queue_cancel","x-xholic-cli":"xholic queue cancel","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/cancel \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue cancel --post-id '<postId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_cancel\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/cancel\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/cancel\",\n  {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/cancel\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/cancel\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/cancel\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/cancel\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId"]},"example":{"postId":"<postId>","dryRun":true}}}}}},"/queue/share-draft":{"post":{"operationId":"queue.share_draft","summary":"Share a draft link","description":"Create a public read-only link to a draft so someone without Xholic can review it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"queue_share_draft","x-xholic-cli":"xholic queue share-draft","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/share-draft \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue share-draft --post-id '<postId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_share_draft\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/share-draft\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/share-draft\",\n  {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/share-draft\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/share-draft\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/share-draft\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/share-draft\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId"]},"example":{"postId":"<postId>","dryRun":true}}}}}},"/queue/revoke-share":{"post":{"operationId":"queue.revoke_share","summary":"Turn off draft links","description":"Turn off every public link to a draft.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"queue_revoke_share","x-xholic-cli":"xholic queue revoke-share","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/revoke-share \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue revoke-share --post-id '<postId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_revoke_share\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/revoke-share\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/revoke-share\",\n  {\n    \"postId\": \"<postId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/revoke-share\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/revoke-share\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/revoke-share\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/revoke-share\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId"]},"example":{"postId":"<postId>","dryRun":true}}}}}},"/queue/add-automation-step":{"post":{"operationId":"queue.add_automation_step","summary":"Add an automation to a live post","description":"Add one automation step to a post that is already live: repost, unrepost, delete, a plug reply after enough likes, or DMs to people who reply with a keyword. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"queue_add_automation_step","x-xholic-cli":"xholic queue add-automation-step","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/add-automation-step \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue add-automation-step --post-id '<postId>' --type 'AUTO_REPOST' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_add_automation_step\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"type\": \"AUTO_REPOST\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/add-automation-step\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"type\": \"AUTO_REPOST\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/add-automation-step\",\n  {\n    \"postId\": \"<postId>\",\n    \"type\": \"AUTO_REPOST\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/add-automation-step\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"type\": \"AUTO_REPOST\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/add-automation-step\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/add-automation-step\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/add-automation-step\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"type":{"type":"string","enum":["AUTO_REPOST","AUTO_UNREPOST","AUTO_DELETE","AUTO_PLUG","AUTO_DM_DISCOVERY"],"description":"The step. Each type takes only its own fields."},"delayMinutes":{"description":"AUTO_REPOST, AUTO_UNREPOST, AUTO_DELETE: minutes after the post went live.","type":"integer","minimum":0,"maximum":9007199254740991},"viewsThreshold":{"description":"AUTO_DELETE: delete only if the post has fewer views than this.","type":"integer","minimum":1,"maximum":9007199254740991},"likesThreshold":{"description":"AUTO_PLUG: likes that trigger the plug reply.","type":"integer","minimum":1,"maximum":9007199254740991},"templateName":{"description":"AUTO_PLUG: a short name for the plug.","type":"string","minLength":1,"maxLength":60},"templateText":{"description":"AUTO_PLUG: the plug reply text.","type":"string","minLength":1,"maxLength":4000},"monitoringWindowMinutes":{"description":"AUTO_PLUG: minutes after posting when watching for likes stops.","type":"integer","minimum":60,"maximum":10080},"replyKeyword":{"description":"AUTO_DM_DISCOVERY: one word repliers type.","type":"string","minLength":1,"maxLength":40},"requireRepost":{"description":"AUTO_DM_DISCOVERY: DM only people who also reposted.","type":"boolean"},"maxRecipients":{"description":"AUTO_DM_DISCOVERY: most DMs to send.","type":"integer","minimum":1,"maximum":100},"messageTemplate":{"description":"AUTO_DM_DISCOVERY: the DM to send.","type":"string","minLength":1},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId","type"]},"example":{"postId":"<postId>","type":"AUTO_REPOST","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/queue/update-automation-step":{"post":{"operationId":"queue.update_automation_step","summary":"Edit a live post's automation","description":"Change a pending automation step on a live post. Send the whole step with its type. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"queue_update_automation_step","x-xholic-cli":"xholic queue update-automation-step","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/update-automation-step \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue update-automation-step --post-id '<postId>' --rule-id '<ruleId>' --type 'AUTO_REPOST' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_update_automation_step\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"ruleId\": \"<ruleId>\",\n    \"type\": \"AUTO_REPOST\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/update-automation-step\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"ruleId\": \"<ruleId>\",\n    \"type\": \"AUTO_REPOST\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/update-automation-step\",\n  {\n    \"postId\": \"<postId>\",\n    \"ruleId\": \"<ruleId>\",\n    \"type\": \"AUTO_REPOST\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/update-automation-step\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"ruleId\": \"<ruleId>\",\n        \"type\": \"AUTO_REPOST\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/update-automation-step\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/update-automation-step\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/update-automation-step\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"type\":\"AUTO_REPOST\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"ruleId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["AUTO_REPOST","AUTO_UNREPOST","AUTO_DELETE","AUTO_PLUG","AUTO_DM_DISCOVERY"],"description":"The step. Each type takes only its own fields."},"delayMinutes":{"description":"AUTO_REPOST, AUTO_UNREPOST, AUTO_DELETE: minutes after the post went live.","type":"integer","minimum":0,"maximum":9007199254740991},"viewsThreshold":{"description":"AUTO_DELETE: delete only if the post has fewer views than this.","type":"integer","minimum":1,"maximum":9007199254740991},"likesThreshold":{"description":"AUTO_PLUG: likes that trigger the plug reply.","type":"integer","minimum":1,"maximum":9007199254740991},"templateName":{"description":"AUTO_PLUG: a short name for the plug.","type":"string","minLength":1,"maxLength":60},"templateText":{"description":"AUTO_PLUG: the plug reply text.","type":"string","minLength":1,"maxLength":4000},"monitoringWindowMinutes":{"description":"AUTO_PLUG: minutes after posting when watching for likes stops.","type":"integer","minimum":60,"maximum":10080},"replyKeyword":{"description":"AUTO_DM_DISCOVERY: one word repliers type.","type":"string","minLength":1,"maxLength":40},"requireRepost":{"description":"AUTO_DM_DISCOVERY: DM only people who also reposted.","type":"boolean"},"maxRecipients":{"description":"AUTO_DM_DISCOVERY: most DMs to send.","type":"integer","minimum":1,"maximum":100},"messageTemplate":{"description":"AUTO_DM_DISCOVERY: the DM to send.","type":"string","minLength":1},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId","ruleId","type"]},"example":{"postId":"<postId>","ruleId":"<ruleId>","type":"AUTO_REPOST","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/queue/remove-automation-step":{"post":{"operationId":"queue.remove_automation_step","summary":"Remove a live post's automation","description":"Remove a pending automation step from a live post before it runs. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["queue"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"queue_remove_automation_step","x-xholic-cli":"xholic queue remove-automation-step","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/queue/remove-automation-step \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic queue remove-automation-step --post-id '<postId>' --rule-id '<ruleId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"queue_remove_automation_step\",\n  \"arguments\": {\n    \"postId\": \"<postId>\",\n    \"ruleId\": \"<ruleId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/queue/remove-automation-step\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"postId\": \"<postId>\",\n    \"ruleId\": \"<ruleId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/queue/remove-automation-step\",\n  {\n    \"postId\": \"<postId>\",\n    \"ruleId\": \"<ruleId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/queue/remove-automation-step\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"postId\": \"<postId>\",\n        \"ruleId\": \"<ruleId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/queue/remove-automation-step\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/queue/remove-automation-step\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/queue/remove-automation-step\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"postId\":\"<postId>\",\"ruleId\":\"<ruleId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1,"maxLength":120,"description":"Xholic scheduled post id, from get_queue."},"ruleId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["postId","ruleId"]},"example":{"postId":"<postId>","ruleId":"<ruleId>","dryRun":true}}}}}},"/composer/rewrite":{"post":{"operationId":"composer.rewrite","summary":"Rewrite with Xholic AI","description":"Only when the user explicitly asks for Xholic's rewriter. Rewrites a post or a selection by an instruction, or reviews the writing (mode review). Uses Xholic AI credits: quote first and pass confirmCredits after the user agrees. Otherwise rewrite it yourself.\n\nUses Xholic AI credits (up to about 8). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["composer"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"composer_rewrite","x-xholic-cli":"xholic composer rewrite","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/composer/rewrite \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Shipping the API today\",\"instruction\":\"<instruction>\",\"mode\":\"selection\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic composer rewrite --text 'Shipping the API today' --instruction '<instruction>' --mode 'selection' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"composer_rewrite\",\n  \"arguments\": {\n    \"text\": \"Shipping the API today\",\n    \"instruction\": \"<instruction>\",\n    \"mode\": \"selection\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/composer/rewrite\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"text\": \"Shipping the API today\",\n    \"instruction\": \"<instruction>\",\n    \"mode\": \"selection\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/composer/rewrite\",\n  {\n    \"text\": \"Shipping the API today\",\n    \"instruction\": \"<instruction>\",\n    \"mode\": \"selection\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/composer/rewrite\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"text\": \"Shipping the API today\",\n        \"instruction\": \"<instruction>\",\n        \"mode\": \"selection\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"text\":\"Shipping the API today\",\"instruction\":\"<instruction>\",\"mode\":\"selection\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/composer/rewrite\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/composer/rewrite\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"text\":\"Shipping the API today\",\"instruction\":\"<instruction>\",\"mode\":\"selection\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/composer/rewrite\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"text\":\"Shipping the API today\",\"instruction\":\"<instruction>\",\"mode\":\"selection\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","maxLength":25000,"description":"The post, or the selected part to rewrite."},"instruction":{"type":"string","minLength":1,"maxLength":500},"context":{"description":"The full post around a selection.","type":"string","maxLength":25000},"mode":{"type":"string","enum":["selection","post","review"]},"maxCharacters":{"type":"integer","minimum":1,"maximum":25000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["text","instruction","mode"]},"example":{"text":"Shipping the API today","instruction":"<instruction>","mode":"selection","dryRun":true}}}}}},"/composer/originality":{"post":{"operationId":"composer.originality","summary":"Originality check with Xholic AI","description":"Only when the user explicitly asks. Xholic AI judges whether a post is original or too close to a source post. Uses Xholic AI credits: quote first and pass confirmCredits after the user agrees. drafts.check is the free check.\n\nUses Xholic AI credits (up to about 4). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["composer"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"composer_originality","x-xholic-cli":"xholic composer originality","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/composer/originality \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"parts\":[\"<part>\"],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic composer originality --parts '<part>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"composer_originality\",\n  \"arguments\": {\n    \"parts\": [\n      \"<part>\"\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/composer/originality\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"parts\": [\n      \"<part>\"\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/composer/originality\",\n  {\n    \"parts\": [\n      \"<part>\"\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/composer/originality\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"parts\": [\n            \"<part>\"\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"parts\":[\"<part>\"],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/composer/originality\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/composer/originality\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"parts\":[\"<part>\"],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/composer/originality\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"parts\":[\"<part>\"],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"parts":{"minItems":1,"maxItems":25,"type":"array","items":{"type":"string","maxLength":25000},"description":"The post, or each thread part in order."},"sourceText":{"description":"The post it was built from.","nullable":true,"type":"string","maxLength":25000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["parts"]},"example":{"parts":["<part>"],"dryRun":true}}}}}},"/replies/prefetch":{"get":{"operationId":"replies.prefetch","summary":"Warm up a reply","description":"Load an X post and its thread ahead of drafting a reply with Xholic's reply writer. Free; no AI.","tags":["replies"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"replies_prefetch","x-xholic-cli":"xholic replies prefetch","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/replies/prefetch?tweetId=%3CtweetId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic replies prefetch --tweet-id '<tweetId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"replies_prefetch\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/replies/prefetch?tweetId=%3CtweetId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/replies/prefetch\", {\n  params: {\n    \"tweetId\": \"<tweetId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/replies/prefetch\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"tweetId\": \"<tweetId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/replies/prefetch?tweetId=%3CtweetId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/replies/prefetch?tweetId=%3CtweetId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/replies/prefetch?tweetId=%3CtweetId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"tweetId","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{1,25}$","description":"X post id (digits)."},"example":"<tweetId>","description":"X post id (digits)."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/replies/select-draft":{"post":{"operationId":"replies.select_draft","summary":"Pick another reply draft","description":"Switch a reply generation to one of its other drafts (already paid for, free). Teaches the reply writer which drafts the user prefers.","tags":["replies"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"replies_select_draft","x-xholic-cli":"xholic replies select-draft","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/replies/select-draft \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"generationId\":\"<generationId>\",\"index\":1,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic replies select-draft --tweet-id '<tweetId>' --generation-id '<generationId>' --index 1 --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"replies_select_draft\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"generationId\": \"<generationId>\",\n    \"index\": 1,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/replies/select-draft\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"generationId\": \"<generationId>\",\n    \"index\": 1,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/replies/select-draft\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"generationId\": \"<generationId>\",\n    \"index\": 1,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/replies/select-draft\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"generationId\": \"<generationId>\",\n        \"index\": 1,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"generationId\":\"<generationId>\",\"index\":1,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/replies/select-draft\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/replies/select-draft\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"generationId\":\"<generationId>\",\"index\":1,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/replies/select-draft\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"generationId\":\"<generationId>\",\"index\":1,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","pattern":"^\\d{1,25}$","description":"X post id (digits)."},"generationId":{"type":"string","pattern":"^rw_[A-Za-z0-9-]{1,100}$","description":"The reply generation id."},"index":{"type":"integer","minimum":0,"maximum":3,"description":"0 is the main draft, 1 the first alternative, and so on."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tweetId","generationId","index"]},"example":{"tweetId":"<tweetId>","generationId":"<generationId>","index":1,"dryRun":true}}}}}},"/replies/get-settings":{"get":{"operationId":"replies.get_settings","summary":"Reply writer settings","description":"The reply writer's custom instructions and whether replies may use the author's name.","tags":["replies"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"replies_get_settings","x-xholic-cli":"xholic replies get-settings","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/replies/get-settings' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic replies get-settings"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"replies_get_settings\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/replies/get-settings\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/replies/get-settings\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/replies/get-settings\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/replies/get-settings\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/replies/get-settings\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/replies/get-settings\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/replies/update-settings":{"post":{"operationId":"replies.update_settings","summary":"Update reply writer settings","description":"Change the reply writer's custom instructions or whether replies may use the author's name. Send at least one. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["replies"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"replies_update_settings","x-xholic-cli":"xholic replies update-settings","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/replies/update-settings \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic replies update-settings --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"replies_update_settings\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/replies/update-settings\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/replies/update-settings\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/replies/update-settings\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/replies/update-settings\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/replies/update-settings\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/replies/update-settings\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"customInstructions":{"nullable":true,"type":"string","maxLength":500},"includeAuthorName":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/composer/mention-suggestions":{"get":{"operationId":"composer.mention_suggestions","summary":"Suggest @mentions","description":"X accounts matching a partial handle, from Xholic's data first. remote 1 allows a small live X search when few match.","tags":["composer"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"composer_mention_suggestions","x-xholic-cli":"xholic composer mention-suggestions","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/composer/mention-suggestions?q=%3Cq%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic composer mention-suggestions --q '<q>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"composer_mention_suggestions\",\n  \"arguments\": {\n    \"q\": \"<q>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/composer/mention-suggestions?q=%3Cq%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/composer/mention-suggestions\", {\n  params: {\n    \"q\": \"<q>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/composer/mention-suggestions\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"q\": \"<q>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/composer/mention-suggestions?q=%3Cq%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/composer/mention-suggestions?q=%3Cq%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/composer/mention-suggestions?q=%3Cq%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_]{1,15}$","description":"The handle typed so far, without @."},"example":"<q>","description":"The handle typed so far, without @."},{"name":"remote","in":"query","required":false,"schema":{"type":"string","enum":["0","1"]}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/remix/generate":{"post":{"operationId":"remix.generate","summary":"Remix a post with Xholic AI","description":"Only when the user explicitly asks for Xholic's remixer. Writes the user's own take on an X post in their voice (3 drafts). Uses Xholic AI credits: quote first and pass confirmCredits after the user agrees. Otherwise write the remix yourself from get_post and get_me.\n\nUses Xholic AI credits (up to about 12). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"remix_generate","x-xholic-cli":"xholic remix generate","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/remix/generate \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"closeness\":1,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic remix generate --tweet-id '<tweetId>' --closeness 1 --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_generate\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"closeness\": 1,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/generate\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"closeness\": 1,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/remix/generate\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"closeness\": 1,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/remix/generate\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"closeness\": 1,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"closeness\":1,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/remix/generate\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/generate\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"closeness\":1,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/generate\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"closeness\":1,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","pattern":"^\\d{1,25}$","description":"X post id (digits)."},"closeness":{"type":"number","minimum":0,"maximum":1,"description":"0 is loosely inspired, 1 stays close to the original."},"customInstructions":{"type":"string","maxLength":500},"remixAction":{"description":"Iterate on currentDraft: shorter, punchier, casual or hot_take.","type":"string","enum":["shorter","punchier","casual","hot_take"]},"maxLength":{"type":"integer","minimum":30,"maximum":2000},"productId":{"description":"Weave in one of the user's products.","type":"string","minLength":1,"maxLength":100},"productContextIntent":{"type":"string","enum":["context","focus"]},"currentDraft":{"type":"string","maxLength":25000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["tweetId","closeness"]},"example":{"tweetId":"<tweetId>","closeness":1,"dryRun":true}}}}}},"/remix/select-draft":{"post":{"operationId":"remix.select_draft","summary":"Pick another remix draft","description":"Switch a remix to another of its drafts. Free; the drafts were already paid for.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"remix_select_draft","x-xholic-cli":"xholic remix select-draft","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/remix/select-draft \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"remixId\":\"<remixId>\",\"index\":1,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic remix select-draft --remix-id '<remixId>' --index 1 --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_select_draft\",\n  \"arguments\": {\n    \"remixId\": \"<remixId>\",\n    \"index\": 1,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/select-draft\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"remixId\": \"<remixId>\",\n    \"index\": 1,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/remix/select-draft\",\n  {\n    \"remixId\": \"<remixId>\",\n    \"index\": 1,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/remix/select-draft\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"remixId\": \"<remixId>\",\n        \"index\": 1,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"remixId\":\"<remixId>\",\"index\":1,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/remix/select-draft\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/select-draft\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"remixId\":\"<remixId>\",\"index\":1,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/select-draft\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"remixId\":\"<remixId>\",\"index\":1,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"remixId":{"type":"string","minLength":1},"index":{"type":"integer","minimum":0,"maximum":9},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["remixId","index"]},"example":{"remixId":"<remixId>","index":1,"dryRun":true}}}}}},"/remix/post":{"post":{"operationId":"remix.post","summary":"Post a remix","description":"Post a remix to X now, optionally with edited text. Call it only when the user asked for this in the conversation; never on your own initiative. Spends a post credit.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"remix_post","x-xholic-cli":"xholic remix post","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/remix/post \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"remixId\":\"<remixId>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic remix post --remix-id '<remixId>' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_post\",\n  \"arguments\": {\n    \"remixId\": \"<remixId>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/post\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"remixId\": \"<remixId>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/remix/post\",\n  {\n    \"remixId\": \"<remixId>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/remix/post\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"remixId\": \"<remixId>\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"remixId\":\"<remixId>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/remix/post\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/post\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"remixId\":\"<remixId>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/post\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"remixId\":\"<remixId>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"remixId":{"type":"string","minLength":1},"remixedText":{"description":"Edited text. Leave out to post the selected draft.","type":"string","minLength":1,"maxLength":25000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["remixId"]},"example":{"remixId":"<remixId>","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/remix/history":{"get":{"operationId":"remix.history","summary":"Remix history","description":"Past remixes with their source posts and drafts, newest first.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"remix_history","x-xholic-cli":"xholic remix history","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/remix/history' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic remix history"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_history\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/history\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/remix/history\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/remix/history\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/remix/history\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/history\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/history\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/remix/list-presets":{"get":{"operationId":"remix.list_presets","summary":"Remix presets","description":"The account's saved custom instructions for remixing.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"remix_list_presets","x-xholic-cli":"xholic remix list-presets","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/remix/list-presets' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic remix list-presets"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_list_presets\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/list-presets\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/remix/list-presets\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/remix/list-presets\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/remix/list-presets\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/list-presets\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/list-presets\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/remix/create-preset":{"post":{"operationId":"remix.create_preset","summary":"Save a remix preset","description":"Save a named custom instruction for remixing. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"remix_create_preset","x-xholic-cli":"xholic remix create-preset","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/remix/create-preset \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic remix create-preset --label '<label>' --instruction '<instruction>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_create_preset\",\n  \"arguments\": {\n    \"label\": \"<label>\",\n    \"instruction\": \"<instruction>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/create-preset\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"label\": \"<label>\",\n    \"instruction\": \"<instruction>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/remix/create-preset\",\n  {\n    \"label\": \"<label>\",\n    \"instruction\": \"<instruction>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/remix/create-preset\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"label\": \"<label>\",\n        \"instruction\": \"<instruction>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/remix/create-preset\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/create-preset\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/create-preset\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":40},"instruction":{"type":"string","minLength":1,"maxLength":500},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["label","instruction"]},"example":{"label":"<label>","instruction":"<instruction>","dryRun":true}}}}}},"/remix/update-preset":{"post":{"operationId":"remix.update_preset","summary":"Edit a remix preset","description":"Change a remix preset's label and instruction. Send both. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"remix_update_preset","x-xholic-cli":"xholic remix update-preset","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/remix/update-preset \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"presetId\":\"<presetId>\",\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic remix update-preset --preset-id '<presetId>' --label '<label>' --instruction '<instruction>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_update_preset\",\n  \"arguments\": {\n    \"presetId\": \"<presetId>\",\n    \"label\": \"<label>\",\n    \"instruction\": \"<instruction>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/update-preset\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"presetId\": \"<presetId>\",\n    \"label\": \"<label>\",\n    \"instruction\": \"<instruction>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/remix/update-preset\",\n  {\n    \"presetId\": \"<presetId>\",\n    \"label\": \"<label>\",\n    \"instruction\": \"<instruction>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/remix/update-preset\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"presetId\": \"<presetId>\",\n        \"label\": \"<label>\",\n        \"instruction\": \"<instruction>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"presetId\":\"<presetId>\",\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/remix/update-preset\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/update-preset\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"presetId\":\"<presetId>\",\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/update-preset\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"presetId\":\"<presetId>\",\"label\":\"<label>\",\"instruction\":\"<instruction>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"presetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":"string","minLength":1,"maxLength":40},"instruction":{"type":"string","minLength":1,"maxLength":500},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["presetId","label","instruction"]},"example":{"presetId":"<presetId>","label":"<label>","instruction":"<instruction>","dryRun":true}}}}}},"/remix/delete-preset":{"post":{"operationId":"remix.delete_preset","summary":"Delete a remix preset","description":"Delete a remix preset. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["remix"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"remix_delete_preset","x-xholic-cli":"xholic remix delete-preset","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/remix/delete-preset \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"presetId\":\"<presetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic remix delete-preset --preset-id '<presetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"remix_delete_preset\",\n  \"arguments\": {\n    \"presetId\": \"<presetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/remix/delete-preset\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"presetId\": \"<presetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/remix/delete-preset\",\n  {\n    \"presetId\": \"<presetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/remix/delete-preset\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"presetId\": \"<presetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"presetId\":\"<presetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/remix/delete-preset\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/remix/delete-preset\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"presetId\":\"<presetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/remix/delete-preset\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"presetId\":\"<presetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"presetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["presetId"]},"example":{"presetId":"<presetId>","dryRun":true}}}}}},"/analytics/growth":{"get":{"operationId":"analytics.growth","summary":"Growth funnel","description":"The follower funnel for the last 7 and 30 days (impressions to profile visits to follows), its weakest step and the profile check score. Stored data only.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"analytics_growth","x-xholic-cli":"xholic analytics growth","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/growth' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics growth"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_growth\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/growth\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/growth\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/growth\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/growth\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/growth\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/growth\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/import-status":{"get":{"operationId":"analytics.import_status","summary":"Analytics sync status","description":"Whether the account's post history is still importing, up to date or delayed, and how far it got.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"analytics_import_status","x-xholic-cli":"xholic analytics import-status","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/import-status' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics import-status"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_import_status\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/import-status\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/import-status\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/import-status\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/import-status\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/import-status\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/import-status\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/export-posts-csv":{"get":{"operationId":"analytics.export_posts_csv","summary":"Export post stats (CSV)","description":"Every post in a period with its numbers as CSV text (up to 5,000 rows). Filters match how_did_it_do.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"analytics_export_posts_csv","x-xholic-cli":"xholic analytics export-posts-csv","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/export-posts-csv' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics export-posts-csv"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_export_posts_csv\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/export-posts-csv\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/export-posts-csv\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/export-posts-csv\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/export-posts-csv\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/export-posts-csv\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/export-posts-csv\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["today","7d","14d","30d","60d","90d","180d","all"]}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"description":"IANA timezone such as America/New_York. Use the user's timezone."},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["ALL","POST","REPLY","REPOST","QUOTE"]}},{"name":"origin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","enum":["NEURON","BRAIN","REMIX","SCHEDULER","EXTENSION","NATIVE_X","UNKNOWN"]},{"type":"string","enum":["ALL"]}]}},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string","enum":["TEXT","IMAGE","VIDEO","LINK","THREAD","ARTICLE"]},{"type":"string","enum":["ALL"]}]}},{"name":"search","in":"query","required":false,"schema":{"type":"string","maxLength":160}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["publishedAt","impressions","engagements","engagementRate","likes","replies","reposts","quotes","bookmarks","profileClicks","urlClicks","followerGain","bookmarkRate","replyRate","shareRate","firstDayImpressions","baselineMultiple"]}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"from","in":"query","required":false,"schema":{"description":"First day, YYYY-MM-DD; overrides range.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"First day, YYYY-MM-DD; overrides range."},{"name":"to","in":"query","required":false,"schema":{"description":"Last day, YYYY-MM-DD.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"Last day, YYYY-MM-DD."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/export-daily-csv":{"get":{"operationId":"analytics.export_daily_csv","summary":"Export daily stats (CSV)","description":"Daily totals for a period (posts, impressions, engagement, follower change) as CSV text.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"analytics_export_daily_csv","x-xholic-cli":"xholic analytics export-daily-csv","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/export-daily-csv' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics export-daily-csv"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_export_daily_csv\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/export-daily-csv\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/export-daily-csv\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/export-daily-csv\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/export-daily-csv\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/export-daily-csv\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/export-daily-csv\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["today","7d","14d","30d","60d","90d","180d","all"]}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"description":"IANA timezone such as America/New_York. Use the user's timezone."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/list-imports":{"get":{"operationId":"analytics.list_imports","summary":"Analytics imports","description":"X analytics CSV files imported into this account, with the days each one covered.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"analytics_list_imports","x-xholic-cli":"xholic analytics list-imports","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/analytics/list-imports' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics list-imports"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_list_imports\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/list-imports\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/analytics/list-imports\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/analytics/list-imports\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/analytics/list-imports\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/list-imports\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/list-imports\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/analytics/import-csv":{"post":{"operationId":"analytics.import_csv","summary":"Import X analytics CSV","description":"Import the account overview CSV exported from X analytics to fill in past days. If the file looks like another account's, it is refused until confirmOwnership is true; ask the user first. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"analytics_import_csv","x-xholic-cli":"xholic analytics import-csv","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/analytics/import-csv \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"csv\":\"<csv>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics import-csv --csv '<csv>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_import_csv\",\n  \"arguments\": {\n    \"csv\": \"<csv>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/import-csv\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"csv\": \"<csv>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/analytics/import-csv\",\n  {\n    \"csv\": \"<csv>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/analytics/import-csv\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"csv\": \"<csv>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"csv\":\"<csv>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/analytics/import-csv\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/import-csv\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"csv\":\"<csv>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/import-csv\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"csv\":\"<csv>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":200000,"description":"The CSV file's text."},"confirmOwnership":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["csv"]},"example":{"csv":"<csv>","dryRun":true}}}}}},"/analytics/delete-import":{"post":{"operationId":"analytics.delete_import","summary":"Remove an analytics import","description":"Remove an imported analytics file and the days it wrote. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["analytics"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"analytics_delete_import","x-xholic-cli":"xholic analytics delete-import","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/analytics/delete-import \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic analytics delete-import --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"analytics_delete_import\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/analytics/delete-import\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/analytics/delete-import\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/analytics/delete-import\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/analytics/delete-import\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/analytics/delete-import\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/analytics/delete-import\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":120,"description":"Import id from analytics.list_imports."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/engage/get-consent":{"get":{"operationId":"engage.get_consent","summary":"Engage guidelines status","description":"Whether the user accepted Engage's guidelines. Engage feeds, mentions and replies need it; until then they answer with a consent error.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"engage_get_consent","x-xholic-cli":"xholic engage get-consent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/engage/get-consent' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic engage get-consent"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_get_consent\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/get-consent\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/engage/get-consent\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/engage/get-consent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/engage/get-consent\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/get-consent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/get-consent\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/engage/accept-consent":{"post":{"operationId":"engage.accept_consent","summary":"Accept Engage guidelines","description":"Record that the user accepted Engage's guidelines for engaging on X. Tell the user they are accepting them and call it only after they explicitly agree in the conversation; never on your own initiative.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_accept_consent","x-xholic-cli":"xholic engage accept-consent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/accept-consent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"version\":\"v2\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage accept-consent --version 'v2' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_accept_consent\",\n  \"arguments\": {\n    \"version\": \"v2\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/accept-consent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"version\": \"v2\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/accept-consent\",\n  {\n    \"version\": \"v2\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/accept-consent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"version\": \"v2\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"version\":\"v2\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/accept-consent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/accept-consent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"version\":\"v2\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/accept-consent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"version\":\"v2\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string","enum":["v2"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["version"]},"example":{"version":"v2","dryRun":true}}}}}},"/engage/list-feeds":{"get":{"operationId":"engage.list_feeds","summary":"Engage feeds","description":"The account's saved Engage feeds (FEEDS) or extension timelines (TIMELINE).","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"engage_list_feeds","x-xholic-cli":"xholic engage list-feeds","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/engage/list-feeds' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic engage list-feeds"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_list_feeds\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/list-feeds\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/engage/list-feeds\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/engage/list-feeds\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/engage/list-feeds\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/list-feeds\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/list-feeds\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"placement","in":"query","required":false,"schema":{"type":"string","enum":["FEEDS","TIMELINE"]}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/engage/create-feed":{"post":{"operationId":"engage.create_feed","summary":"Create an Engage feed","description":"Save a feed of posts to engage with: a topic, a contact list, an X list, or one account (timelines only). Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_create_feed","x-xholic-cli":"xholic engage create-feed","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/create-feed \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage create-feed --name 'Example' --type 'TOPIC' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_create_feed\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"type\": \"TOPIC\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/create-feed\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"type\": \"TOPIC\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/create-feed\",\n  {\n    \"name\": \"Example\",\n    \"type\": \"TOPIC\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/create-feed\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"type\": \"TOPIC\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/create-feed\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/create-feed\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/create-feed\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","enum":["TOPIC","FOLLOWING","CONTACT_LIST","X_LIST","USER"],"description":"TOPIC (query holds 1-5 keywords), CONTACT_LIST (contactListId), X_LIST (xListId), USER (query holds a handle; TIMELINE placement only)."},"placement":{"description":"FEEDS (default) or TIMELINE. It can't change later.","type":"string","enum":["FEEDS","TIMELINE"]},"query":{"nullable":true,"type":"string","maxLength":500},"contactListId":{"nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"xListId":{"nullable":true,"type":"string","pattern":"^\\d{1,25}$"},"excludedHandles":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":16}},"excludedTerms":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name","type"]},"example":{"name":"Example","type":"TOPIC","dryRun":true}}}}}},"/engage/create-feeds":{"post":{"operationId":"engage.create_feeds","summary":"Create several Engage feeds","description":"Save up to 8 Engage feeds in one call. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_create_feeds","x-xholic-cli":"xholic engage create-feeds","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/create-feeds \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"feeds\":[{\"name\":\"Example\",\"type\":\"TOPIC\"}],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage create-feeds --feeds '[{\"name\":\"Example\",\"type\":\"TOPIC\"}]' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_create_feeds\",\n  \"arguments\": {\n    \"feeds\": [\n      {\n        \"name\": \"Example\",\n        \"type\": \"TOPIC\"\n      }\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/create-feeds\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"feeds\": [\n      {\n        \"name\": \"Example\",\n        \"type\": \"TOPIC\"\n      }\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/create-feeds\",\n  {\n    \"feeds\": [\n      {\n        \"name\": \"Example\",\n        \"type\": \"TOPIC\"\n      }\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/create-feeds\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"feeds\": [\n            {\n                \"name\": \"Example\",\n                \"type\": \"TOPIC\"\n            }\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"feeds\":[{\"name\":\"Example\",\"type\":\"TOPIC\"}],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/create-feeds\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/create-feeds\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"feeds\":[{\"name\":\"Example\",\"type\":\"TOPIC\"}],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/create-feeds\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"feeds\":[{\"name\":\"Example\",\"type\":\"TOPIC\"}],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"feeds":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","enum":["TOPIC","FOLLOWING","CONTACT_LIST","X_LIST","USER"],"description":"TOPIC (query holds 1-5 keywords), CONTACT_LIST (contactListId), X_LIST (xListId), USER (query holds a handle; TIMELINE placement only)."},"placement":{"description":"FEEDS (default) or TIMELINE. It can't change later.","type":"string","enum":["FEEDS","TIMELINE"]},"query":{"nullable":true,"type":"string","maxLength":500},"contactListId":{"nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"xListId":{"nullable":true,"type":"string","pattern":"^\\d{1,25}$"},"excludedHandles":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":16}},"excludedTerms":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}}},"required":["name","type"]}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["feeds"]},"example":{"feeds":[{"name":"Example","type":"TOPIC"}],"dryRun":true}}}}}},"/engage/update-feed":{"post":{"operationId":"engage.update_feed","summary":"Edit an Engage feed","description":"Change a saved feed. Send the whole feed (name, type, query...); placement can't change. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_update_feed","x-xholic-cli":"xholic engage update-feed","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/update-feed \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage update-feed --id '<id>' --name 'Example' --type 'TOPIC' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_update_feed\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"type\": \"TOPIC\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/update-feed\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"type\": \"TOPIC\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/update-feed\",\n  {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"type\": \"TOPIC\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/update-feed\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"name\": \"Example\",\n        \"type\": \"TOPIC\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/update-feed\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/update-feed\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/update-feed\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"name\":\"Example\",\"type\":\"TOPIC\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Feed id from engage.list_feeds."},"name":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","enum":["TOPIC","FOLLOWING","CONTACT_LIST","X_LIST","USER"],"description":"TOPIC (query holds 1-5 keywords), CONTACT_LIST (contactListId), X_LIST (xListId), USER (query holds a handle; TIMELINE placement only)."},"placement":{"description":"FEEDS (default) or TIMELINE. It can't change later.","type":"string","enum":["FEEDS","TIMELINE"]},"query":{"nullable":true,"type":"string","maxLength":500},"contactListId":{"nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"xListId":{"nullable":true,"type":"string","pattern":"^\\d{1,25}$"},"excludedHandles":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":16}},"excludedTerms":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","name","type"]},"example":{"id":"<id>","name":"Example","type":"TOPIC","dryRun":true}}}}}},"/engage/delete-feed":{"post":{"operationId":"engage.delete_feed","summary":"Delete an Engage feed","description":"Delete a saved Engage feed. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_delete_feed","x-xholic-cli":"xholic engage delete-feed","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/delete-feed \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage delete-feed --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_delete_feed\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/delete-feed\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/delete-feed\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/delete-feed\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/delete-feed\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/delete-feed\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/delete-feed\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Feed id from engage.list_feeds."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/engage/feed":{"get":{"operationId":"engage.feed","summary":"Read an Engage feed","description":"Posts to engage with from a saved feed (feedId) or an ad-hoc topic search (type TOPIC + query), top or latest. Posts the user already replied to are hidden by default.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"engage_feed","x-xholic-cli":"xholic engage feed","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/engage/feed' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic engage feed"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_feed\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/feed\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/engage/feed\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/engage/feed\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/engage/feed\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/feed\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/feed\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"feedId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["TOPIC","FOLLOWING","CONTACT_LIST","X_LIST","USER"]}},{"name":"query","in":"query","required":false,"schema":{"type":"string","maxLength":500}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["TOP","LATEST"]}},{"name":"cursor","in":"query","required":false,"schema":{"description":"From the previous page, for more.","type":"string","maxLength":2000},"description":"From the previous page, for more."},{"name":"hideReplied","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/engage/set-item-state":{"post":{"operationId":"engage.set_item_state","summary":"Hide or mark a post replied","description":"Hide a post from Engage feeds (a skip), or mark it replied or not replied.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_set_item_state","x-xholic-cli":"xholic engage set-item-state","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/set-item-state \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage set-item-state --tweet-id '<tweetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_set_item_state\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/set-item-state\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/set-item-state\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/set-item-state\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/set-item-state\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/set-item-state\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/set-item-state\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","pattern":"^\\d{1,25}$","description":"X post id (digits)."},"hidden":{"type":"boolean"},"replied":{"type":"boolean"},"accountId":{"description":"The post author's X user id, when known.","type":"string","pattern":"^\\d{1,25}$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tweetId"]},"example":{"tweetId":"<tweetId>","dryRun":true}}}}}},"/engage/clear-skips":{"post":{"operationId":"engage.clear_skips","summary":"Clear hidden posts","description":"Bring back every post the account hid from Engage feeds. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["engage"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"engage_clear_skips","x-xholic-cli":"xholic engage clear-skips","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/engage/clear-skips \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic engage clear-skips --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engage_clear_skips\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/engage/clear-skips\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/engage/clear-skips\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/engage/clear-skips\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/engage/clear-skips\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/engage/clear-skips\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/engage/clear-skips\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/inspiration/explain-structure":{"post":{"operationId":"inspiration.explain_structure","summary":"Explain a post's structure","description":"Xholic AI breaks down why an Inspiration post works: hook, structure and reusable pattern. Cached posts are free. Uses Xholic AI credits otherwise: quote first and pass confirmCredits after the user agrees. You can usually explain it yourself from get_post.\n\nUses Xholic AI credits (up to about 1). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["inspiration"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"inspiration_explain_structure","x-xholic-cli":"xholic inspiration explain-structure","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/inspiration/explain-structure \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic inspiration explain-structure --tweet-id '<tweetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"inspiration_explain_structure\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/inspiration/explain-structure\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/inspiration/explain-structure\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/inspiration/explain-structure\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/inspiration/explain-structure\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/inspiration/explain-structure\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/inspiration/explain-structure\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","minLength":1,"maxLength":100},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["tweetId"]},"example":{"tweetId":"<tweetId>","dryRun":true}}}}}},"/library/save":{"post":{"operationId":"library.save","summary":"Save a post","description":"Save an X post to the user's library by its id. Use library.save_by_url for a URL.","tags":["library"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"library_save","x-xholic-cli":"xholic library save","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/library/save \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic library save --tweet-id '<tweetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"library_save\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/library/save\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/library/save\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/library/save\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/library/save\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/library/save\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/library/save\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","pattern":"^\\d{1,25}$","description":"X post id (digits)."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tweetId"]},"example":{"tweetId":"<tweetId>","dryRun":true}}}}}},"/library/save-by-url":{"post":{"operationId":"library.save_by_url","summary":"Save a post by URL","description":"Save an X post to the user's library from its URL.","tags":["library"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"library_save_by_url","x-xholic-cli":"xholic library save-by-url","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/library/save-by-url \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic library save-by-url --url 'https://example.com/hooks/xholic' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"library_save_by_url\",\n  \"arguments\": {\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/library/save-by-url\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/library/save-by-url\",\n  {\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/library/save-by-url\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"url\": \"https://example.com/hooks/xholic\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/library/save-by-url\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/library/save-by-url\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/library/save-by-url\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["url"]},"example":{"url":"https://example.com/hooks/xholic","dryRun":true}}}}}},"/library/unsave":{"post":{"operationId":"library.unsave","summary":"Remove a saved post","description":"Remove a post from the user's library. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["library"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"library_unsave","x-xholic-cli":"xholic library unsave","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/library/unsave \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic library unsave --tweet-id '<tweetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"library_unsave\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/library/unsave\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/library/unsave\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/library/unsave\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/library/unsave\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/library/unsave\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/library/unsave\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","pattern":"^\\d{1,25}$","description":"X post id (digits)."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tweetId"]},"example":{"tweetId":"<tweetId>","dryRun":true}}}}}},"/collections/list":{"get":{"operationId":"collections.list","summary":"Collections","description":"The user's saved-post collections with counts.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"collections_list","x-xholic-cli":"xholic collections list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/collections/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic collections list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_list\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/collections/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/collections/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/collections/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/collections/create":{"post":{"operationId":"collections.create","summary":"Create a collection","description":"Create a collection for saved posts. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"collections_create","x-xholic-cli":"xholic collections create","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/collections/create \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic collections create --name 'Example' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_create\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/create\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/collections/create\",\n  {\n    \"name\": \"Example\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/collections/create\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/collections/create\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/create\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/create\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"emoji":{"type":"string","maxLength":10},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name"]},"example":{"name":"Example","dryRun":true}}}}}},"/collections/hooks":{"post":{"operationId":"collections.hooks","summary":"Hooks collection","description":"Get the user's Hooks collection (for saved hook ideas), creating it if it doesn't exist.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"collections_hooks","x-xholic-cli":"xholic collections hooks","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/collections/hooks \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic collections hooks --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_hooks\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/hooks\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/collections/hooks\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/collections/hooks\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/collections/hooks\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/hooks\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/hooks\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/collections/move":{"post":{"operationId":"collections.move","summary":"Move a saved post","description":"Put a saved post in a collection, or take it out with collectionId null.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"collections_move","x-xholic-cli":"xholic collections move","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/collections/move \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tweetId\":\"<tweetId>\",\"collectionId\":\"<collectionId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic collections move --tweet-id '<tweetId>' --collection-id '<collectionId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_move\",\n  \"arguments\": {\n    \"tweetId\": \"<tweetId>\",\n    \"collectionId\": \"<collectionId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/move\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"tweetId\": \"<tweetId>\",\n    \"collectionId\": \"<collectionId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/collections/move\",\n  {\n    \"tweetId\": \"<tweetId>\",\n    \"collectionId\": \"<collectionId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/collections/move\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"tweetId\": \"<tweetId>\",\n        \"collectionId\": \"<collectionId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"tweetId\":\"<tweetId>\",\"collectionId\":\"<collectionId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/collections/move\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/move\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"tweetId\":\"<tweetId>\",\"collectionId\":\"<collectionId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/move\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"tweetId\":\"<tweetId>\",\"collectionId\":\"<collectionId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweetId":{"type":"string","minLength":1,"maxLength":100},"collectionId":{"nullable":true,"type":"string","minLength":1,"maxLength":100,"description":"Collection id from collections.list."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["tweetId","collectionId"]},"example":{"tweetId":"<tweetId>","collectionId":"<collectionId>","dryRun":true}}}}}},"/collections/reorder":{"post":{"operationId":"collections.reorder","summary":"Reorder collections","description":"Set the display order of collections, by id.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"collections_reorder","x-xholic-cli":"xholic collections reorder","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/collections/reorder \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"orderedCollectionIds\":[\"<orderedCollectionId>\"],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic collections reorder --ordered-collection-ids '<orderedCollectionId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_reorder\",\n  \"arguments\": {\n    \"orderedCollectionIds\": [\n      \"<orderedCollectionId>\"\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/reorder\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"orderedCollectionIds\": [\n      \"<orderedCollectionId>\"\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/collections/reorder\",\n  {\n    \"orderedCollectionIds\": [\n      \"<orderedCollectionId>\"\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/collections/reorder\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"orderedCollectionIds\": [\n            \"<orderedCollectionId>\"\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"orderedCollectionIds\":[\"<orderedCollectionId>\"],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/collections/reorder\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/reorder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"orderedCollectionIds\":[\"<orderedCollectionId>\"],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/reorder\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"orderedCollectionIds\":[\"<orderedCollectionId>\"],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orderedCollectionIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["orderedCollectionIds"]},"example":{"orderedCollectionIds":["<orderedCollectionId>"],"dryRun":true}}}}}},"/collections/rename":{"post":{"operationId":"collections.rename","summary":"Rename a collection","description":"Rename a collection or change its emoji (null removes it). Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"collections_rename","x-xholic-cli":"xholic collections rename","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/collections/rename \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic collections rename --id '<id>' --name 'Example' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_rename\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/rename\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/collections/rename\",\n  {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/collections/rename\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"name\": \"Example\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/collections/rename\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/rename\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/rename\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"Collection id from collections.list."},"name":{"type":"string","minLength":1,"maxLength":100},"emoji":{"nullable":true,"type":"string","maxLength":10},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","name"]},"example":{"id":"<id>","name":"Example","dryRun":true}}}}}},"/collections/delete":{"post":{"operationId":"collections.delete","summary":"Delete a collection","description":"Delete a collection. Its posts stay saved, uncategorized. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["collections"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"collections_delete","x-xholic-cli":"xholic collections delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/collections/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic collections delete --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"collections_delete\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/collections/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/collections/delete\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/collections/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/collections/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/collections/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/collections/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"Collection id from collections.list."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/articles/list":{"get":{"operationId":"articles.list","summary":"Articles","description":"The account's X Articles (drafts, scheduled, published), newest first.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"articles_list","x-xholic-cli":"xholic articles list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/articles/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic articles list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_list\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/articles/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/articles/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/articles/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","enum":["ALL"]},{"type":"string","enum":["DRAFT","SCHEDULED","PUBLISHING","PUBLISHED","FAILED","ARCHIVED"]}]}},{"name":"search","in":"query","required":false,"schema":{"type":"string","maxLength":120}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/articles/create":{"post":{"operationId":"articles.create","summary":"Create an article","description":"Start a new X Article draft with a title. Then write its body yourself and save it with update_article. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"create_article","x-xholic-cli":"xholic articles create","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/create \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles create --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"create_article\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/create\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/create\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/create\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/create\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/create\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/create\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","maxLength":200},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/articles/eligibility":{"get":{"operationId":"articles.eligibility","summary":"Can this account publish articles","description":"Whether the X account can publish Articles (X requires Premium) and why not.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"articles_eligibility","x-xholic-cli":"xholic articles eligibility","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/articles/eligibility' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic articles eligibility"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_eligibility\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/eligibility\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/articles/eligibility\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/articles/eligibility\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/articles/eligibility\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/eligibility\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/eligibility\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/articles/cover-usage":{"get":{"operationId":"articles.cover_usage","summary":"AI cover allowance","description":"How many AI article covers are left today and this period.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"articles_cover_usage","x-xholic-cli":"xholic articles cover-usage","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/articles/cover-usage' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic articles cover-usage"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_cover_usage\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/cover-usage\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/articles/cover-usage\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/articles/cover-usage\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/articles/cover-usage\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/cover-usage\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/cover-usage\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/articles/get":{"get":{"operationId":"articles.get","summary":"Get an article","description":"One article with its title, subtitle, document, assets, status and version.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"articles_get","x-xholic-cli":"xholic articles get","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/articles/get?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic articles get --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_get\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/get?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/articles/get\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/articles/get\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/articles/get?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/get?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/get?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"example":"<id>","description":"Article id from articles.list."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/articles/update":{"post":{"operationId":"articles.update","summary":"Edit an article","description":"Save an article's title, subtitle or body. Pass the current version from articles.get; it returns the new version. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"update_article","x-xholic-cli":"xholic articles update","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/update \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"version\":1,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles update --id '<id>' --version 1 --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"update_article\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"version\": 1,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/update\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"version\": 1,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/update\",\n  {\n    \"id\": \"<id>\",\n    \"version\": 1,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/update\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"version\": 1,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"version\":1,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/update\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/update\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"version\":1,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/update\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"version\":1,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"title":{"type":"string","minLength":1,"maxLength":200},"subtitle":{"nullable":true,"type":"string","maxLength":280},"document":{"description":"The whole body as a Tiptap/ProseMirror JSON document: {type:\"doc\",content:[paragraph, heading, bulletList, image... nodes]}. See docs.xholic.ai/api/articles.","type":"object","properties":{"type":{"type":"string","enum":["doc"]}},"required":["type"],"additionalProperties":{}},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The article's current version, from articles.get. A stale version is refused so edits never overwrite each other."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","version"]},"example":{"id":"<id>","version":1,"dryRun":true}}}}}},"/articles/delete":{"post":{"operationId":"articles.delete","summary":"Delete an article","description":"Delete an article from Xholic. It does not delete one already published on X. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_delete","x-xholic-cli":"xholic articles delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles delete --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_delete\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/delete\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/articles/duplicate":{"post":{"operationId":"articles.duplicate","summary":"Duplicate an article","description":"Copy an article into a new draft.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_duplicate","x-xholic-cli":"xholic articles duplicate","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/duplicate \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles duplicate --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_duplicate\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/duplicate\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/duplicate\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/duplicate\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/duplicate\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/duplicate\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/duplicate\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/articles/ai-run":{"post":{"operationId":"articles.ai_run","summary":"Article AI","description":"Only when the user explicitly asks for Xholic's article AI. Queues an outline, full draft, selection rewrite/expand/shorten, titles, conclusion, teaser post or thread, or an AI cover image. Price depends on kind and model. Uses Xholic AI credits: quote first and pass confirmCredits after the user agrees. Read the result with articles.get. Otherwise write the text yourself.\n\nUses Xholic AI credits (up to about 150). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_ai_run","x-xholic-cli":"xholic articles ai-run","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/ai-run \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"kind\":\"OUTLINE\",\"idempotencyKey\":\"<idempotencyKey>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles ai-run --id '<id>' --kind 'OUTLINE' --idempotency-key '<idempotencyKey>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_ai_run\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"kind\": \"OUTLINE\",\n    \"idempotencyKey\": \"<idempotencyKey>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/ai-run\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"kind\": \"OUTLINE\",\n    \"idempotencyKey\": \"<idempotencyKey>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/ai-run\",\n  {\n    \"id\": \"<id>\",\n    \"kind\": \"OUTLINE\",\n    \"idempotencyKey\": \"<idempotencyKey>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/ai-run\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"kind\": \"OUTLINE\",\n        \"idempotencyKey\": \"<idempotencyKey>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"kind\":\"OUTLINE\",\"idempotencyKey\":\"<idempotencyKey>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/ai-run\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/ai-run\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"kind\":\"OUTLINE\",\"idempotencyKey\":\"<idempotencyKey>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/ai-run\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"kind\":\"OUTLINE\",\"idempotencyKey\":\"<idempotencyKey>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"kind":{"type":"string","enum":["OUTLINE","FULL_ARTICLE","REWRITE_SELECTION","EXPAND_SELECTION","SHORTEN_SELECTION","TITLE_SUGGESTIONS","CONCLUSION","TEASER_POST","TEASER_THREAD","COVER","COVER_EDIT"]},"model":{"description":"luna fast, terra balanced (default), sol deep.","type":"string","enum":["luna","terra","sol"]},"instructions":{"type":"string","maxLength":4000},"selectedText":{"description":"Required for REWRITE_SELECTION, EXPAND_SELECTION and SHORTEN_SELECTION.","type":"string","maxLength":20000},"coverStyle":{"type":"string","enum":["surprise_me","editorial","minimal","bold_typography","illustration"]},"sourceAssetId":{"description":"Required for COVER_EDIT: the cover to edit.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":120,"description":"A unique key for this run so a retry never queues it twice."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["id","kind","idempotencyKey"]},"example":{"id":"<id>","kind":"OUTLINE","idempotencyKey":"<idempotencyKey>","dryRun":true}}}}}},"/articles/create-asset-upload":{"post":{"operationId":"articles.create_asset_upload","summary":"Upload an article image","description":"Start an image upload for an article cover or inline image. Returns an assetId and upload URL; PUT the bytes there, then call articles.finalize_asset.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_create_asset_upload","x-xholic-cli":"xholic articles create-asset-upload","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/create-asset-upload \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"kind\":\"COVER\",\"filename\":\"<filename>\",\"mimeType\":\"image/jpeg\",\"byteSize\":1,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles create-asset-upload --id '<id>' --kind 'COVER' --filename '<filename>' --mime-type 'image/jpeg' --byte-size 1 --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_create_asset_upload\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"kind\": \"COVER\",\n    \"filename\": \"<filename>\",\n    \"mimeType\": \"image/jpeg\",\n    \"byteSize\": 1,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/create-asset-upload\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"kind\": \"COVER\",\n    \"filename\": \"<filename>\",\n    \"mimeType\": \"image/jpeg\",\n    \"byteSize\": 1,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/create-asset-upload\",\n  {\n    \"id\": \"<id>\",\n    \"kind\": \"COVER\",\n    \"filename\": \"<filename>\",\n    \"mimeType\": \"image/jpeg\",\n    \"byteSize\": 1,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/create-asset-upload\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"kind\": \"COVER\",\n        \"filename\": \"<filename>\",\n        \"mimeType\": \"image/jpeg\",\n        \"byteSize\": 1,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"kind\":\"COVER\",\"filename\":\"<filename>\",\"mimeType\":\"image/jpeg\",\"byteSize\":1,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/create-asset-upload\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/create-asset-upload\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"kind\":\"COVER\",\"filename\":\"<filename>\",\"mimeType\":\"image/jpeg\",\"byteSize\":1,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/create-asset-upload\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"kind\":\"COVER\",\"filename\":\"<filename>\",\"mimeType\":\"image/jpeg\",\"byteSize\":1,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"kind":{"type":"string","enum":["COVER","INLINE"]},"filename":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"]},"byteSize":{"type":"integer","minimum":1,"maximum":5242880},"width":{"type":"integer","minimum":1,"maximum":16384},"height":{"type":"integer","minimum":1,"maximum":16384},"altText":{"type":"string","maxLength":1000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","kind","filename","mimeType","byteSize"]},"example":{"id":"<id>","kind":"COVER","filename":"<filename>","mimeType":"image/jpeg","byteSize":1,"dryRun":true}}}}}},"/articles/finalize-asset":{"post":{"operationId":"articles.finalize_asset","summary":"Finish an article image upload","description":"Mark an article image upload finished after the bytes were PUT to the upload URL.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_finalize_asset","x-xholic-cli":"xholic articles finalize-asset","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/finalize-asset \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles finalize-asset --id '<id>' --asset-id '<assetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_finalize_asset\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"assetId\": \"<assetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/finalize-asset\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"assetId\": \"<assetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/finalize-asset\",\n  {\n    \"id\": \"<id>\",\n    \"assetId\": \"<assetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/finalize-asset\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"assetId\": \"<assetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/finalize-asset\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/finalize-asset\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/finalize-asset\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"assetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","assetId"]},"example":{"id":"<id>","assetId":"<assetId>","dryRun":true}}}}}},"/articles/import-klipy":{"post":{"operationId":"articles.import_klipy","summary":"Add a GIF or meme to an article","description":"Copy a KLIPY GIF or meme (from media.browse_klipy) into an article as its cover or an inline image.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_import_klipy","x-xholic-cli":"xholic articles import-klipy","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/import-klipy \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"kind\":\"COVER\",\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles import-klipy --id '<id>' --kind 'COVER' --type 'gifs' --slug '<slug>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_import_klipy\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"kind\": \"COVER\",\n    \"type\": \"gifs\",\n    \"slug\": \"<slug>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/import-klipy\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"kind\": \"COVER\",\n    \"type\": \"gifs\",\n    \"slug\": \"<slug>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/import-klipy\",\n  {\n    \"id\": \"<id>\",\n    \"kind\": \"COVER\",\n    \"type\": \"gifs\",\n    \"slug\": \"<slug>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/import-klipy\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"kind\": \"COVER\",\n        \"type\": \"gifs\",\n        \"slug\": \"<slug>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"kind\":\"COVER\",\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/import-klipy\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/import-klipy\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"kind\":\"COVER\",\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/import-klipy\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"kind\":\"COVER\",\"type\":\"gifs\",\"slug\":\"<slug>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"kind":{"type":"string","enum":["COVER","INLINE"]},"type":{"type":"string","enum":["gifs","memes"]},"slug":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z0-9_-]+$","description":"The item's slug from media.browse_klipy."},"altText":{"type":"string","maxLength":1000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","kind","type","slug"]},"example":{"id":"<id>","kind":"COVER","type":"gifs","slug":"<slug>","dryRun":true}}}}}},"/articles/delete-asset":{"post":{"operationId":"articles.delete_asset","summary":"Remove an article image","description":"Remove an image from an article. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_delete_asset","x-xholic-cli":"xholic articles delete-asset","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/delete-asset \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles delete-asset --id '<id>' --asset-id '<assetId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_delete_asset\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"assetId\": \"<assetId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/delete-asset\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"assetId\": \"<assetId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/delete-asset\",\n  {\n    \"id\": \"<id>\",\n    \"assetId\": \"<assetId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/delete-asset\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"assetId\": \"<assetId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/delete-asset\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/delete-asset\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/delete-asset\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"assetId\":\"<assetId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"assetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","assetId"]},"example":{"id":"<id>","assetId":"<assetId>","dryRun":true}}}}}},"/articles/schedule":{"post":{"operationId":"articles.schedule","summary":"Schedule an article","description":"Schedule an article to publish on X at a time. Pass the current version from articles.get. Call it only when the user asked for this in the conversation; never on your own initiative. Spends a post credit when it goes live.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"schedule_article","x-xholic-cli":"xholic articles schedule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/schedule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles schedule --id '<id>' --scheduled-at '2026-11-03T09:00' --timezone 'America/New_York' --version 1 --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"schedule_article\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"version\": 1,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/schedule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"version\": 1,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/schedule\",\n  {\n    \"id\": \"<id>\",\n    \"scheduledAt\": \"2026-11-03T09:00\",\n    \"timezone\": \"America/New_York\",\n    \"version\": 1,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/schedule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"scheduledAt\": \"2026-11-03T09:00\",\n        \"timezone\": \"America/New_York\",\n        \"version\": 1,\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/schedule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/schedule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/schedule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"scheduledAt\":\"2026-11-03T09:00\",\"timezone\":\"America/New_York\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"scheduledAt":{"type":"string","minLength":1,"maxLength":40,"description":"When to publish, as an ISO time with offset such as 2026-10-25T10:00:00-04:00."},"timezone":{"type":"string","minLength":1,"maxLength":100,"description":"IANA timezone such as America/New_York. Use the user's timezone."},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The article's current version, from articles.get. A stale version is refused so edits never overwrite each other."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","scheduledAt","timezone","version"]},"example":{"id":"<id>","scheduledAt":"2026-11-03T09:00","timezone":"America/New_York","version":1,"dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/articles/publish":{"post":{"operationId":"articles.publish","summary":"Publish an article now","description":"Publish an article to X now. Pass the current version from articles.get. Call it only when the user asked for this in the conversation; never on your own initiative. Spends a post credit.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"publish_article","x-xholic-cli":"xholic articles publish","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/publish \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles publish --id '<id>' --version 1 --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"publish_article\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"version\": 1,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/publish\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"version\": 1,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/publish\",\n  {\n    \"id\": \"<id>\",\n    \"version\": 1,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/publish\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"version\": 1,\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/publish\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/publish\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/publish\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"version\":1,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The article's current version, from articles.get. A stale version is refused so edits never overwrite each other."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","version"]},"example":{"id":"<id>","version":1,"dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/articles/cancel-schedule":{"post":{"operationId":"articles.cancel_schedule","summary":"Unschedule an article","description":"Take a scheduled article out of the queue; it stays a draft.","tags":["articles"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"articles_cancel_schedule","x-xholic-cli":"xholic articles cancel-schedule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/articles/cancel-schedule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic articles cancel-schedule --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"articles_cancel_schedule\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/articles/cancel-schedule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/articles/cancel-schedule\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/articles/cancel-schedule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/articles/cancel-schedule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/articles/cancel-schedule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/articles/cancel-schedule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Article id from articles.list."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/workers/create-ready-made":{"post":{"operationId":"workers.create_ready_made","summary":"Create the ready-made Worker","description":"Create the preset Worker built from the account's context (voice, creators it already has posts for, products). Fails while a ready-made Worker exists; rebuild that one instead. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_create_ready_made","x-xholic-cli":"xholic workers create-ready-made","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/create-ready-made \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers create-ready-made --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_create_ready_made\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/create-ready-made\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/create-ready-made\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/create-ready-made\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/create-ready-made\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/create-ready-made\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/create-ready-made\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/workers/rebuild-ready-made":{"post":{"operationId":"workers.rebuild_ready_made","summary":"Rebuild the ready-made Worker","description":"Refresh the ready-made Worker's creators and brief from the account's current context. Name, schedule, drafts and runs stay; no run starts. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_rebuild_ready_made","x-xholic-cli":"xholic workers rebuild-ready-made","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/rebuild-ready-made \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers rebuild-ready-made --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_rebuild_ready_made\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/rebuild-ready-made\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/rebuild-ready-made\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/rebuild-ready-made\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/rebuild-ready-made\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/rebuild-ready-made\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/rebuild-ready-made\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":160,"description":"Worker id from get_workers."},"keepInstructions":{"description":"Keep the user's own brief and refresh only voice and creators.","type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/workers/cancel-queued-run":{"post":{"operationId":"workers.cancel_queued_run","summary":"Stop a queued Worker run","description":"Stop a Worker run that is queued and hasn't started yet. Its credits are returned. A run that already started can't be stopped.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_cancel_queued_run","x-xholic-cli":"xholic workers cancel-queued-run","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/cancel-queued-run \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers cancel-queued-run --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_cancel_queued_run\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/cancel-queued-run\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/cancel-queued-run\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/cancel-queued-run\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/cancel-queued-run\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/cancel-queued-run\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/cancel-queued-run\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":160,"description":"Worker id from get_workers."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/workers/runs":{"get":{"operationId":"workers.runs","summary":"Worker runs","description":"Recent Worker runs, newest first: status, trigger, credits and why a run failed or was skipped.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"workers_runs","x-xholic-cli":"xholic workers runs","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/workers/runs' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic workers runs"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_runs\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/runs\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/workers/runs\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/workers/runs\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/workers/runs\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/runs\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/runs\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/workers/voice":{"get":{"operationId":"workers.voice","summary":"Takes and expertise","description":"The account's takes (opinions) and expertise areas that Workers write from, each marked as mined or added by the user.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"workers_voice","x-xholic-cli":"xholic workers voice","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/workers/voice' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic workers voice"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_voice\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/voice\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/workers/voice\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/workers/voice\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/workers/voice\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/voice\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/voice\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/workers/add-take":{"post":{"operationId":"workers.add_take","summary":"Add a take","description":"Add an opinion the user holds, in their words, for Workers to write from. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_add_take","x-xholic-cli":"xholic workers add-take","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/add-take \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Shipping the API today\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers add-take --text 'Shipping the API today' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_add_take\",\n  \"arguments\": {\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/add-take\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/add-take\",\n  {\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/add-take\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"text\": \"Shipping the API today\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"text\":\"Shipping the API today\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/add-take\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/add-take\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"text\":\"Shipping the API today\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/add-take\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"text\":\"Shipping the API today\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":8,"maxLength":200},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["text"]},"example":{"text":"Shipping the API today","dryRun":true}}}}}},"/workers/remove-take":{"post":{"operationId":"workers.remove_take","summary":"Remove a take","description":"Remove a take so Workers stop writing from it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_remove_take","x-xholic-cli":"xholic workers remove-take","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/remove-take \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers remove-take --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_remove_take\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/remove-take\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/remove-take\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/remove-take\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/remove-take\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/remove-take\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/remove-take\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"description":"Take id from workers.voice."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/workers/add-expertise":{"post":{"operationId":"workers.add_expertise","summary":"Add an expertise area","description":"Add a subject the account teaches, so Workers write knowledge posts about it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_add_expertise","x-xholic-cli":"xholic workers add-expertise","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/add-expertise \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers add-expertise --name 'Example' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_add_expertise\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/add-expertise\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/add-expertise\",\n  {\n    \"name\": \"Example\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/add-expertise\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/add-expertise\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/add-expertise\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/add-expertise\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":3,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name"]},"example":{"name":"Example","dryRun":true}}}}}},"/workers/remove-expertise":{"post":{"operationId":"workers.remove_expertise","summary":"Remove an expertise area","description":"Remove an expertise area and its insight cards. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_remove_expertise","x-xholic-cli":"xholic workers remove-expertise","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/remove-expertise \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers remove-expertise --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_remove_expertise\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/remove-expertise\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/remove-expertise\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/remove-expertise\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/remove-expertise\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/remove-expertise\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/remove-expertise\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"description":"Expertise area id from workers.voice."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/workers/review-draft":{"post":{"operationId":"workers.review_draft","summary":"Review a Worker draft","description":"Move a Worker draft: DRAFT keeps it in the user's drafts, DISMISSED throws it away, TO_REVIEW puts it back in review. When dismissing because it isn't the user's opinion, pass reason NOT_MY_OPINION so Workers learn. To post or schedule it, use schedule_post with its text. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"review_worker_draft","x-xholic-cli":"xholic workers review-draft","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/review-draft \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"status\":\"TO_REVIEW\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers review-draft --id '<id>' --status 'TO_REVIEW' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"review_worker_draft\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"status\": \"TO_REVIEW\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/review-draft\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"status\": \"TO_REVIEW\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/review-draft\",\n  {\n    \"id\": \"<id>\",\n    \"status\": \"TO_REVIEW\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/review-draft\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"status\": \"TO_REVIEW\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"status\":\"TO_REVIEW\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/review-draft\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/review-draft\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"status\":\"TO_REVIEW\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/review-draft\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"status\":\"TO_REVIEW\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":160,"description":"Worker draft id from get_worker_drafts."},"status":{"type":"string","enum":["TO_REVIEW","DRAFT","DISMISSED"]},"reason":{"description":"Only with DISMISSED: why, when it teaches the Workers something.","type":"string","enum":["NOT_MY_OPINION"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","status"]},"example":{"id":"<id>","status":"TO_REVIEW","dryRun":true}}}}}},"/workers/draft-feedback":{"post":{"operationId":"workers.draft_feedback","summary":"More or less like this","description":"Tell the Workers to write more or fewer drafts like this one. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_draft_feedback","x-xholic-cli":"xholic workers draft-feedback","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/draft-feedback \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"action\":\"MORE_LIKE_THIS\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers draft-feedback --id '<id>' --action 'MORE_LIKE_THIS' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_draft_feedback\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"action\": \"MORE_LIKE_THIS\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/draft-feedback\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"action\": \"MORE_LIKE_THIS\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/draft-feedback\",\n  {\n    \"id\": \"<id>\",\n    \"action\": \"MORE_LIKE_THIS\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/draft-feedback\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"action\": \"MORE_LIKE_THIS\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"action\":\"MORE_LIKE_THIS\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/draft-feedback\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/draft-feedback\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"action\":\"MORE_LIKE_THIS\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/draft-feedback\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"action\":\"MORE_LIKE_THIS\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":160,"description":"Worker draft id from get_worker_drafts."},"action":{"type":"string","enum":["MORE_LIKE_THIS","LESS_LIKE_THIS"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","action"]},"example":{"id":"<id>","action":"MORE_LIKE_THIS","dryRun":true}}}}}},"/workers/draft-meme":{"post":{"operationId":"workers.draft_meme","summary":"Worker meme image","description":"The reaction image (GIF or meme) attached to a Worker meme draft. The first call picks one.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_draft_meme","x-xholic-cli":"xholic workers draft-meme","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/draft-meme \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers draft-meme --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_draft_meme\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/draft-meme\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/draft-meme\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/draft-meme\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/draft-meme\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/draft-meme\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/draft-meme\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Worker draft id of a meme draft."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/workers/set-draft-meme":{"post":{"operationId":"workers.set_draft_meme","summary":"Change a Worker meme image","description":"Swap or remove the reaction image on a Worker meme draft. Pass pick null to remove it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["workers"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"workers_set_draft_meme","x-xholic-cli":"xholic workers set-draft-meme","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/workers/set-draft-meme \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"kind\":\"gifs\",\"pick\":{},\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic workers set-draft-meme --id '<id>' --kind 'gifs' --pick '{}' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"workers_set_draft_meme\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"kind\": \"gifs\",\n    \"pick\": {},\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/workers/set-draft-meme\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"kind\": \"gifs\",\n    \"pick\": {},\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/workers/set-draft-meme\",\n  {\n    \"id\": \"<id>\",\n    \"kind\": \"gifs\",\n    \"pick\": {},\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/workers/set-draft-meme\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"kind\": \"gifs\",\n        \"pick\": {},\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"kind\":\"gifs\",\"pick\":{},\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/workers/set-draft-meme\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/workers/set-draft-meme\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"kind\":\"gifs\",\"pick\":{},\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/workers/set-draft-meme\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"kind\":\"gifs\",\"pick\":{},\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Worker draft id of a meme draft."},"kind":{"type":"string","enum":["gifs","memes"]},"pick":{"nullable":true,"description":"A pick as returned by workers.draft_meme, or null to remove the image.","type":"object","properties":{},"additionalProperties":{}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","kind","pick"]},"example":{"id":"<id>","kind":"gifs","pick":{},"dryRun":true}}}}}},"/signals/dashboard":{"get":{"operationId":"signals.dashboard","summary":"Signals overview","description":"Every Signals agent with its status, sources, last run and lead counts, plus the month's scoring quota and any ready-made or product agent that needs a rebuild.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_dashboard","x-xholic-cli":"xholic signals dashboard","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/dashboard' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals dashboard"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_dashboard\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/dashboard\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/dashboard\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/dashboard\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/dashboard\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/dashboard\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/dashboard\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/search-profiles":{"get":{"operationId":"signals.search_profiles","summary":"Find accounts to watch","description":"Search X accounts by name or handle to watch in a Signals agent (Profile or Followers sources). Stored profiles first, then live X.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_search_profiles","x-xholic-cli":"xholic signals search-profiles","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/search-profiles?q=%3Cq%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals search-profiles --q '<q>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_search_profiles\",\n  \"arguments\": {\n    \"q\": \"<q>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/search-profiles?q=%3Cq%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/search-profiles\", {\n  params: {\n    \"q\": \"<q>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/search-profiles\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"q\": \"<q>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/search-profiles?q=%3Cq%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/search-profiles?q=%3Cq%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/search-profiles?q=%3Cq%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":80},"example":"<q>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/source-details":{"get":{"operationId":"signals.source_details","summary":"Watched source details","description":"Names and avatars for X accounts and X lists a Signals agent watches.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_source_details","x-xholic-cli":"xholic signals source-details","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/source-details' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals source-details"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_source_details\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/source-details\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/source-details\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/source-details\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/source-details\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/source-details\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/source-details\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"usernames","in":"query","required":false,"schema":{"description":"Comma-separated X usernames without @, up to 30.","type":"string","maxLength":600},"description":"Comma-separated X usernames without @, up to 30."},{"name":"listIds","in":"query","required":false,"schema":{"description":"Comma-separated numeric X list ids, up to 30.","type":"string","maxLength":2000},"description":"Comma-separated numeric X list ids, up to 30."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/create-ready-made":{"post":{"operationId":"signals.create_ready_made","summary":"Create the ready-made Signals agent","description":"Create the one-click Signals agent built from the account's context and tested searches. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_create_ready_made","x-xholic-cli":"xholic signals create-ready-made","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/create-ready-made \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals create-ready-made --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_create_ready_made\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/create-ready-made\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/create-ready-made\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/create-ready-made\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/create-ready-made\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/create-ready-made\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/create-ready-made\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/signals/rebuild-ready-made":{"post":{"operationId":"signals.rebuild_ready_made","summary":"Rebuild the ready-made Signals agent","description":"Refresh the ready-made Signals agent from the account's current context. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_rebuild_ready_made","x-xholic-cli":"xholic signals rebuild-ready-made","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/rebuild-ready-made \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals rebuild-ready-made --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_rebuild_ready_made\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/rebuild-ready-made\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/rebuild-ready-made\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/rebuild-ready-made\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/rebuild-ready-made\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/rebuild-ready-made\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/rebuild-ready-made\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Signals agent id."},"keepTargeting":{"description":"Keep the user's own description and rubric and refresh only the searches.","type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/signals/expand-ready-made":{"post":{"operationId":"signals.expand_ready_made","summary":"Add searches to the ready-made agent","description":"Top the ready-made Signals agent up to the paid plan's size with more searches from the profile, keeping its current ones. Not available on a trial. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_expand_ready_made","x-xholic-cli":"xholic signals expand-ready-made","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/expand-ready-made \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals expand-ready-made --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_expand_ready_made\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/expand-ready-made\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/expand-ready-made\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/expand-ready-made\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/expand-ready-made\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/expand-ready-made\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/expand-ready-made\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Signals agent id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/signals/dismiss-expand":{"post":{"operationId":"signals.dismiss_expand","summary":"Hide the add-searches offer","description":"Hide the offer to add more searches to the ready-made Signals agent, for good.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_dismiss_expand","x-xholic-cli":"xholic signals dismiss-expand","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/dismiss-expand \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals dismiss-expand --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_dismiss_expand\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/dismiss-expand\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/dismiss-expand\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/dismiss-expand\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/dismiss-expand\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/dismiss-expand\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/dismiss-expand\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Signals agent id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/signals/rebuild-product-agent":{"post":{"operationId":"signals.rebuild_product_agent","summary":"Update a Find customers agent","description":"Rebuild a product's Find customers agent after the product changed. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"signals_rebuild_product_agent","x-xholic-cli":"xholic signals rebuild-product-agent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/rebuild-product-agent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals rebuild-product-agent --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_rebuild_product_agent\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/rebuild-product-agent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/rebuild-product-agent\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/rebuild-product-agent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/rebuild-product-agent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/rebuild-product-agent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/rebuild-product-agent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Signals agent id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/signals/run-agent":{"post":{"operationId":"signals.run_agent","summary":"Run a Signals agent now","description":"Queue a Signals agent to search for leads now instead of waiting for its schedule. Leads it scores count toward the month's Signals quota, and each agent has a few manual runs per 24 hours. Returns right away; new leads arrive in get_leads. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"run_signal_agent","x-xholic-cli":"xholic signals run-agent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/signals/run-agent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic signals run-agent --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"run_signal_agent\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/run-agent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/signals/run-agent\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/signals/run-agent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/signals/run-agent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/run-agent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/run-agent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Signals agent id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/signals/runs":{"get":{"operationId":"signals.runs","summary":"Signals runs","description":"Recent Signals agent runs, newest first, with what each found and scored.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_runs","x-xholic-cli":"xholic signals runs","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/runs' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals runs"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_runs\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/runs\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/runs\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/runs\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/runs\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/runs\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/runs\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/agent-brief":{"get":{"operationId":"signals.agent_brief","summary":"Agent's customer brief","description":"One Signals agent's weekly brief: themes, questions and competitors its leads talk about, with the people and posts behind each. Says NOT_ENOUGH under 3 leads.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_agent_brief","x-xholic-cli":"xholic signals agent-brief","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/agent-brief?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals agent-brief --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_agent_brief\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/agent-brief?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/agent-brief\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/agent-brief\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/agent-brief?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/agent-brief?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/agent-brief?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Signals agent id."},"example":"<id>","description":"Signals agent id."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/market-brief":{"get":{"operationId":"signals.market_brief","summary":"Market brief","description":"The weekly brief across all of the account's Signals agents: one view of what the market asks for and who to reply to.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_market_brief","x-xholic-cli":"xholic signals market-brief","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/market-brief' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals market-brief"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_market_brief\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/market-brief\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/market-brief\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/market-brief\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/market-brief\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/market-brief\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/market-brief\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/signals/products":{"get":{"operationId":"signals.products","summary":"Products and their customer agents","description":"The account's products, each with its Find customers agent (and build progress) and competitors.","tags":["signals"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"signals_products","x-xholic-cli":"xholic signals products","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/signals/products' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic signals products"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"signals_products\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/signals/products\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/signals/products\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/signals/products\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/signals/products\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/signals/products\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/signals/products\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/competitors/discover":{"post":{"operationId":"competitors.discover","summary":"Discover competitors","description":"Find a product's competitors and add them as suggestions to accept or dismiss. Works once per product per cooldown. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["competitors"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"competitors_discover","x-xholic-cli":"xholic competitors discover","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/competitors/discover \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic competitors discover --product-id '<productId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"competitors_discover\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/competitors/discover\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/competitors/discover\",\n  {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/competitors/discover\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/competitors/discover\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/competitors/discover\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/competitors/discover\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Product id from signals.products."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId"]},"example":{"productId":"<productId>","dryRun":true}}}}}},"/competitors/set-status":{"post":{"operationId":"competitors.set_status","summary":"Accept or remove a competitor","description":"ACCEPTED keeps a suggested competitor; DISMISSED removes any competitor. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["competitors"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"competitors_set_status","x-xholic-cli":"xholic competitors set-status","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/competitors/set-status \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"competitorId\":\"<competitorId>\",\"status\":\"ACCEPTED\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic competitors set-status --product-id '<productId>' --competitor-id '<competitorId>' --status 'ACCEPTED' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"competitors_set_status\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"competitorId\": \"<competitorId>\",\n    \"status\": \"ACCEPTED\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/competitors/set-status\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"competitorId\": \"<competitorId>\",\n    \"status\": \"ACCEPTED\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/competitors/set-status\",\n  {\n    \"productId\": \"<productId>\",\n    \"competitorId\": \"<competitorId>\",\n    \"status\": \"ACCEPTED\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/competitors/set-status\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"competitorId\": \"<competitorId>\",\n        \"status\": \"ACCEPTED\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"competitorId\":\"<competitorId>\",\"status\":\"ACCEPTED\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/competitors/set-status\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/competitors/set-status\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"competitorId\":\"<competitorId>\",\"status\":\"ACCEPTED\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/competitors/set-status\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"competitorId\":\"<competitorId>\",\"status\":\"ACCEPTED\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Product id from signals.products."},"competitorId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Competitor id from competitors.list."},"status":{"type":"string","enum":["ACCEPTED","DISMISSED"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId","competitorId","status"]},"example":{"productId":"<productId>","competitorId":"<competitorId>","status":"ACCEPTED","dryRun":true}}}}}},"/leads/set-status":{"post":{"operationId":"leads.set_status","summary":"Mark a lead","description":"Mark a lead COLLECTED (keep), CONTACTED (reached out) or DISMISSED (not now). Pass suppress true with DISMISSED to never surface this person again. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["leads"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"set_lead_status","x-xholic-cli":"xholic leads set-status","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/leads/set-status \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"status\":\"COLLECTED\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic leads set-status --id '<id>' --status 'COLLECTED' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"set_lead_status\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"status\": \"COLLECTED\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/leads/set-status\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"status\": \"COLLECTED\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/leads/set-status\",\n  {\n    \"id\": \"<id>\",\n    \"status\": \"COLLECTED\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/leads/set-status\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"status\": \"COLLECTED\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"status\":\"COLLECTED\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/leads/set-status\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/leads/set-status\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"status\":\"COLLECTED\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/leads/set-status\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"status\":\"COLLECTED\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Lead id from get_leads."},"status":{"type":"string","enum":["COLLECTED","CONTACTED","DISMISSED"]},"suppress":{"description":"Never show this person as a lead again.","type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","status"]},"example":{"id":"<id>","status":"COLLECTED","dryRun":true}}}}}},"/contact-lists/list":{"get":{"operationId":"contact_lists.list","summary":"Contact lists","description":"The account's contact lists with member counts, including which one is the close-accounts list. Use a list's id with the other contact tools.","tags":["contact_lists"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_contact_lists","x-xholic-cli":"xholic contact-lists list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contact-lists/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contact-lists list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_contact_lists\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contact-lists/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contact-lists/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contact-lists/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contact-lists/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contact-lists/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contact-lists/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/contact-lists/create":{"post":{"operationId":"contact_lists.create","summary":"Create a contact list","description":"Create a contact list. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contact_lists"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contact_lists_create","x-xholic-cli":"xholic contact-lists create","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contact-lists/create \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Example\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contact-lists create --name 'Example' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contact_lists_create\",\n  \"arguments\": {\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contact-lists/create\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contact-lists/create\",\n  {\n    \"name\": \"Example\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contact-lists/create\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"name\": \"Example\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"name\":\"Example\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contact-lists/create\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contact-lists/create\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"name\":\"Example\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contact-lists/create\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"name\":\"Example\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"description":{"nullable":true,"type":"string","maxLength":1500},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["name"]},"example":{"name":"Example","dryRun":true}}}}}},"/contact-lists/rename":{"post":{"operationId":"contact_lists.rename","summary":"Rename a contact list","description":"Rename a contact list. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contact_lists"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contact_lists_rename","x-xholic-cli":"xholic contact-lists rename","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contact-lists/rename \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contact-lists rename --id '<id>' --name 'Example' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contact_lists_rename\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contact-lists/rename\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contact-lists/rename\",\n  {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contact-lists/rename\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"name\": \"Example\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contact-lists/rename\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contact-lists/rename\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contact-lists/rename\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"name\":\"Example\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact list id."},"name":{"type":"string","minLength":1,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","name"]},"example":{"id":"<id>","name":"Example","dryRun":true}}}}}},"/contact-lists/delete":{"post":{"operationId":"contact_lists.delete","summary":"Delete a contact list","description":"Delete a contact list and its memberships. The people stay in other lists. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contact_lists"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contact_lists_delete","x-xholic-cli":"xholic contact-lists delete","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contact-lists/delete \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contact-lists delete --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contact_lists_delete\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contact-lists/delete\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contact-lists/delete\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contact-lists/delete\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contact-lists/delete\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contact-lists/delete\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contact-lists/delete\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact list id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/contact-lists/set-close-accounts":{"post":{"operationId":"contact_lists.set_close_accounts","summary":"Use a list as close accounts","description":"Turn a list into the account's close-accounts list (people whose posts Home and Engage surface first), or turn that off. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contact_lists"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contact_lists_set_close_accounts","x-xholic-cli":"xholic contact-lists set-close-accounts","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contact-lists/set-close-accounts \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"enabled\":false,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contact-lists set-close-accounts --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contact_lists_set_close_accounts\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"enabled\": false,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contact-lists/set-close-accounts\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"enabled\": false,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contact-lists/set-close-accounts\",\n  {\n    \"id\": \"<id>\",\n    \"enabled\": false,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contact-lists/set-close-accounts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"enabled\": False,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"enabled\":false,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contact-lists/set-close-accounts\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contact-lists/set-close-accounts\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"enabled\":false,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contact-lists/set-close-accounts\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"enabled\":false,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact list id."},"enabled":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","enabled"]},"example":{"id":"<id>","enabled":false,"dryRun":true}}}}}},"/contacts/add-to-list":{"post":{"operationId":"contacts.add_to_list","summary":"Add someone to a contact list","description":"Add an X account to a contact list by handle. Looks the profile up on X when Xholic doesn't have it yet. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"add_to_contact_list","x-xholic-cli":"xholic contacts add-to-list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/add-to-list \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"listId\":\"<listId>\",\"handle\":\"@founder\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts add-to-list --list-id '<listId>' --handle '@founder' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"add_to_contact_list\",\n  \"arguments\": {\n    \"listId\": \"<listId>\",\n    \"handle\": \"@founder\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/add-to-list\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"listId\": \"<listId>\",\n    \"handle\": \"@founder\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/add-to-list\",\n  {\n    \"listId\": \"<listId>\",\n    \"handle\": \"@founder\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/add-to-list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"listId\": \"<listId>\",\n        \"handle\": \"@founder\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"listId\":\"<listId>\",\"handle\":\"@founder\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/add-to-list\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/add-to-list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"listId\":\"<listId>\",\"handle\":\"@founder\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/add-to-list\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"listId\":\"<listId>\",\"handle\":\"@founder\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact list id from get_contact_lists."},"handle":{"type":"string","minLength":1,"maxLength":120,"description":"X handle like @name, or a link to their profile."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["listId","handle"]},"example":{"listId":"<listId>","handle":"@founder","dryRun":true}}}}}},"/contacts/add":{"post":{"operationId":"contacts.add","summary":"Add a known person to a list","description":"Add a person Xholic already has (by X user id, e.g. from a lead or contacts.search_profiles) to a contact list. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_add","x-xholic-cli":"xholic contacts add","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/add \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"listId\":\"<listId>\",\"creatorId\":\"<creatorId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts add --list-id '<listId>' --creator-id '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_add\",\n  \"arguments\": {\n    \"listId\": \"<listId>\",\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/add\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"listId\": \"<listId>\",\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/add\",\n  {\n    \"listId\": \"<listId>\",\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/add\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"listId\": \"<listId>\",\n        \"creatorId\": \"<creatorId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"listId\":\"<listId>\",\"creatorId\":\"<creatorId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/add\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/add\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"listId\":\"<listId>\",\"creatorId\":\"<creatorId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/add\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"listId\":\"<listId>\",\"creatorId\":\"<creatorId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact list id."},"creatorId":{"type":"string","minLength":1,"maxLength":64,"description":"The person's numeric X user id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["listId","creatorId"]},"example":{"listId":"<listId>","creatorId":"<creatorId>","dryRun":true}}}}}},"/contacts/update":{"post":{"operationId":"contacts.update","summary":"Update a contact","description":"Change a contact's status (NEW, SAVED, CONTACTED, DISMISSED) or its note. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_update","x-xholic-cli":"xholic contacts update","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/update \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts update --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_update\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/update\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/update\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/update\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/update\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/update\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/update\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact (list membership) id from get_contacts."},"status":{"type":"string","enum":["NEW","SAVED","CONTACTED","DISMISSED"]},"note":{"nullable":true,"type":"string","maxLength":4000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/contacts/remove":{"post":{"operationId":"contacts.remove","summary":"Remove from a list","description":"Remove a contact from its list. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_remove","x-xholic-cli":"xholic contacts remove","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/remove \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts remove --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_remove\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/remove\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/remove\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/remove\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/remove\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/remove\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/remove\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact (list membership) id from get_contacts."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/contacts/save-note":{"post":{"operationId":"contacts.save_note","summary":"Save a note on a person","description":"Add a note about a person, or edit one by passing its id. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_save_note","x-xholic-cli":"xholic contacts save-note","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/save-note \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"note\":\"<note>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts save-note --creator-id '<creatorId>' --note '<note>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_save_note\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"note\": \"<note>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/save-note\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"note\": \"<note>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/save-note\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"note\": \"<note>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/save-note\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"note\": \"<note>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"note\":\"<note>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/save-note\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/save-note\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"note\":\"<note>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/save-note\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"note\":\"<note>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d+$","description":"The person's numeric X user id."},"id":{"description":"An existing note's id, to edit it.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"note":{"type":"string","minLength":1,"maxLength":4000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorId","note"]},"example":{"creatorId":"<creatorId>","note":"<note>","dryRun":true}}}}}},"/contacts/delete-note":{"post":{"operationId":"contacts.delete_note","summary":"Delete a note","description":"Delete a note about a person. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_delete_note","x-xholic-cli":"xholic contacts delete-note","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/delete-note \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts delete-note --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_delete_note\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/delete-note\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/delete-note\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/delete-note\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/delete-note\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/delete-note\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/delete-note\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Note id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/contacts/search-profiles":{"get":{"operationId":"contacts.search_profiles","summary":"Find people to add","description":"Search X accounts by name or handle to add to a contact list. Stored profiles first, then a capped live X lookup.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"contacts_search_profiles","x-xholic-cli":"xholic contacts search-profiles","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contacts/search-profiles?q=%3Cq%3E&listId=%3ClistId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts search-profiles --q '<q>' --list-id '<listId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_search_profiles\",\n  \"arguments\": {\n    \"q\": \"<q>\",\n    \"listId\": \"<listId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/search-profiles?q=%3Cq%3E&listId=%3ClistId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contacts/search-profiles\", {\n  params: {\n    \"q\": \"<q>\",\n    \"listId\": \"<listId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contacts/search-profiles\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"q\": \"<q>\",\n        \"listId\": \"<listId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contacts/search-profiles?q=%3Cq%3E&listId=%3ClistId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/search-profiles?q=%3Cq%3E&listId=%3ClistId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/search-profiles?q=%3Cq%3E&listId=%3ClistId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":120},"example":"<q>"},{"name":"listId","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The contact list you'll add them to."},"example":"<listId>","description":"The contact list you'll add them to."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/contacts/profile":{"get":{"operationId":"contacts.profile","summary":"Contact profile","description":"Everything Xholic knows about one person: profile, lists, notes, engagement with the account, DMs and, with leadId, why they were found as a lead.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"contacts_profile","x-xholic-cli":"xholic contacts profile","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contacts/profile?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts profile --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_profile\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/profile?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contacts/profile\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contacts/profile\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contacts/profile?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/profile?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/profile?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"description":"The person's numeric X user id."},"example":"<id>","description":"The person's numeric X user id."},{"name":"leadId","in":"query","required":false,"schema":{"description":"A lead id, to include that lead's details.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"A lead id, to include that lead's details."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/leads/rate":{"post":{"operationId":"leads.rate","summary":"Rate a lead","description":"Mark a lead as a FIT or NOT_FIT, with an optional short reason, so the Signals agent learns who to find. Pass verdict null to clear the rating. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["leads"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"rate_lead","x-xholic-cli":"xholic leads rate","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/leads/rate \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"verdict\":\"FIT\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic leads rate --id '<id>' --verdict 'FIT' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"rate_lead\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"verdict\": \"FIT\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/leads/rate\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"verdict\": \"FIT\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/leads/rate\",\n  {\n    \"id\": \"<id>\",\n    \"verdict\": \"FIT\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/leads/rate\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"verdict\": \"FIT\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"verdict\":\"FIT\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/leads/rate\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/leads/rate\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"verdict\":\"FIT\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/leads/rate\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"verdict\":\"FIT\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Lead id from get_leads."},"verdict":{"nullable":true,"type":"string","enum":["FIT","NOT_FIT"]},"reason":{"nullable":true,"type":"string","minLength":1,"maxLength":200},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","verdict"]},"example":{"id":"<id>","verdict":"FIT","dryRun":true}}}}}},"/contacts/follower-import":{"get":{"operationId":"contacts.follower_import","summary":"Follower import status","description":"Whether the account's own followers have been imported into Contacts, and the latest import's progress.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"contacts_follower_import","x-xholic-cli":"xholic contacts follower-import","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contacts/follower-import' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts follower-import"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_follower_import\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/follower-import\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contacts/follower-import\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contacts/follower-import\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contacts/follower-import\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/follower-import\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/follower-import\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/contacts/import-followers":{"post":{"operationId":"contacts.import_followers","summary":"Import my followers","description":"Queue an import of the account's own X followers into Contacts. Runs in the background within the plan's contact limits. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_import_followers","x-xholic-cli":"xholic contacts import-followers","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/import-followers \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts import-followers --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_import_followers\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/import-followers\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/import-followers\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/import-followers\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/import-followers\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/import-followers\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/import-followers\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/contacts/imports":{"get":{"operationId":"contacts.imports","summary":"Contact imports","description":"X list imports into contact lists, with their progress.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"contacts_imports","x-xholic-cli":"xholic contacts imports","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/contacts/imports' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts imports"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_imports\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/imports\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/contacts/imports\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/contacts/imports\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/contacts/imports\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/imports\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/imports\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/contacts/import-x-list":{"post":{"operationId":"contacts.import_x_list","summary":"Import an X list","description":"Queue an import of a public X list's members into a contact list. Runs in the background within the plan's contact limits. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_import_x_list","x-xholic-cli":"xholic contacts import-x-list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/import-x-list \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"listId\":\"<listId>\",\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts import-x-list --list-id '<listId>' --url 'https://example.com/hooks/xholic' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_import_x_list\",\n  \"arguments\": {\n    \"listId\": \"<listId>\",\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/import-x-list\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"listId\": \"<listId>\",\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/import-x-list\",\n  {\n    \"listId\": \"<listId>\",\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/import-x-list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"listId\": \"<listId>\",\n        \"url\": \"https://example.com/hooks/xholic\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"listId\":\"<listId>\",\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/import-x-list\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/import-x-list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"listId\":\"<listId>\",\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/import-x-list\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"listId\":\"<listId>\",\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Contact list to import into."},"url":{"type":"string","maxLength":300,"description":"Link to a public X list."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["listId","url"]},"example":{"listId":"<listId>","url":"https://example.com/hooks/xholic","dryRun":true}}}}}},"/contacts/cancel-import":{"post":{"operationId":"contacts.cancel_import","summary":"Stop a contact import","description":"Stop a running X list import. People already imported stay.","tags":["contacts"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"contacts_cancel_import","x-xholic-cli":"xholic contacts cancel-import","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/contacts/cancel-import \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic contacts cancel-import --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"contacts_cancel_import\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/contacts/cancel-import\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/contacts/cancel-import\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/contacts/cancel-import\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/contacts/cancel-import\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/contacts/cancel-import\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/contacts/cancel-import\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Import id from contacts.imports."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/dashboard":{"get":{"operationId":"dm.dashboard","summary":"DM overview","description":"Direct messages at a glance: sender state (paused, stopped, needs reconnect), today's usage and limits, active campaigns and unread replies.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_dashboard","x-xholic-cli":"xholic dm dashboard","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/dashboard' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm dashboard"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_dashboard\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/dashboard\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/dashboard\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/dashboard\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/dashboard\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/dashboard\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/dashboard\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/preview-recipients":{"post":{"operationId":"dm.preview_recipients","summary":"Find people to DM","description":"Find people to message from a post's repliers, a search, handles, an X list, recent interactions or a contact list, with whether each can be messaged. Returns the recipients (with preview tokens) that send_dms takes.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_preview_recipients","x-xholic-cli":"xholic dm preview-recipients","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/preview-recipients \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"type\":\"FROM_TWEET\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm preview-recipients --type 'FROM_TWEET' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_preview_recipients\",\n  \"arguments\": {\n    \"type\": \"FROM_TWEET\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/preview-recipients\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"type\": \"FROM_TWEET\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/preview-recipients\",\n  {\n    \"type\": \"FROM_TWEET\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/preview-recipients\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"type\": \"FROM_TWEET\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"type\":\"FROM_TWEET\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/preview-recipients\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/preview-recipients\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"type\":\"FROM_TWEET\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/preview-recipients\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"type\":\"FROM_TWEET\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["FROM_TWEET","SEARCH","HANDLES","X_LIST","INTERACTIONS","CONTACT_LIST"],"description":"Where to find people: FROM_TWEET (repliers/reposters of tweetUrl), SEARCH (query), HANDLES (handles), X_LIST (listUrl or numeric listId), INTERACTIONS (people who replied to or reposted the account in the last days), CONTACT_LIST (listId of a contact list)."},"tweetUrl":{"type":"string","maxLength":2048,"format":"uri"},"includeReplies":{"type":"boolean"},"includeReposts":{"type":"boolean"},"keyword":{"description":"FROM_TWEET: only replies matching one of these comma-separated terms.","nullable":true,"type":"string","maxLength":120},"excludeMessagedForPost":{"type":"boolean"},"continuation":{"description":"FROM_TWEET: the continuation from a previous preview, to scan deeper.","nullable":true,"type":"object","properties":{},"additionalProperties":{}},"query":{"type":"string","minLength":1,"maxLength":80},"handles":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"description":"X handle like @name, or a link to their profile."}},"listId":{"description":"X_LIST: numeric X list id. CONTACT_LIST: the contact list id.","nullable":true,"type":"string","maxLength":64},"listUrl":{"nullable":true,"type":"string","maxLength":2048,"format":"uri"},"days":{"type":"integer","minimum":1,"maximum":7},"skipQueued":{"type":"boolean"},"skipCooldown":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["type"]},"example":{"type":"FROM_TWEET","dryRun":true}}}}}},"/dm/quick-send":{"post":{"operationId":"dm.quick_send","summary":"Send DMs now","description":"Send one message to up to 500 people found with dm.preview_recipients, paced safely from the user's X account. Write the message yourself; variables like [first] personalise it. Only pass confirmedConsent true after the user confirmed these people agreed to or expect the message. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"send_dms","x-xholic-cli":"xholic dm quick-send","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/quick-send \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"messageTemplate\":\"<messageTemplate>\",\"confirmedConsent\":true,\"recipients\":[{\"creatorId\":\"<creatorId>\",\"sourceType\":\"FROM_TWEET\",\"previewToken\":\"<previewToken>\"}],\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm quick-send --message-template '<messageTemplate>' --confirmed-consent --recipients '[{\"creatorId\":\"<creatorId>\",\"sourceType\":\"FROM_TWEET\",\"previewToken\":\"<previewToken>\"}]' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"send_dms\",\n  \"arguments\": {\n    \"messageTemplate\": \"<messageTemplate>\",\n    \"confirmedConsent\": true,\n    \"recipients\": [\n      {\n        \"creatorId\": \"<creatorId>\",\n        \"sourceType\": \"FROM_TWEET\",\n        \"previewToken\": \"<previewToken>\"\n      }\n    ],\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/quick-send\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"messageTemplate\": \"<messageTemplate>\",\n    \"confirmedConsent\": true,\n    \"recipients\": [\n      {\n        \"creatorId\": \"<creatorId>\",\n        \"sourceType\": \"FROM_TWEET\",\n        \"previewToken\": \"<previewToken>\"\n      }\n    ],\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/quick-send\",\n  {\n    \"messageTemplate\": \"<messageTemplate>\",\n    \"confirmedConsent\": true,\n    \"recipients\": [\n      {\n        \"creatorId\": \"<creatorId>\",\n        \"sourceType\": \"FROM_TWEET\",\n        \"previewToken\": \"<previewToken>\"\n      }\n    ],\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/quick-send\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"messageTemplate\": \"<messageTemplate>\",\n        \"confirmedConsent\": True,\n        \"recipients\": [\n            {\n                \"creatorId\": \"<creatorId>\",\n                \"sourceType\": \"FROM_TWEET\",\n                \"previewToken\": \"<previewToken>\"\n            }\n        ],\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"messageTemplate\":\"<messageTemplate>\",\"confirmedConsent\":true,\"recipients\":[{\"creatorId\":\"<creatorId>\",\"sourceType\":\"FROM_TWEET\",\"previewToken\":\"<previewToken>\"}],\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/quick-send\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/quick-send\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"messageTemplate\":\"<messageTemplate>\",\"confirmedConsent\":true,\"recipients\":[{\"creatorId\":\"<creatorId>\",\"sourceType\":\"FROM_TWEET\",\"previewToken\":\"<previewToken>\"}],\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/quick-send\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"messageTemplate\":\"<messageTemplate>\",\"confirmedConsent\":true,\"recipients\":[{\"creatorId\":\"<creatorId>\",\"sourceType\":\"FROM_TWEET\",\"previewToken\":\"<previewToken>\"}],\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"nullable":true,"type":"string","minLength":1,"maxLength":80},"messageTemplate":{"type":"string","minLength":1,"maxLength":5000,"description":"The message. Variables: [first], [name], [handle], [location], [followers], list fields such as [first_line], with optional fallbacks like [first|there]; spintax like {Hi|Hey}. Write it yourself in the user's voice."},"confirmedConsent":{"type":"boolean","enum":[true]},"recipients":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"sourceType":{"type":"string","enum":["FROM_TWEET","SEARCH","HANDLES","X_LIST","INTERACTIONS","CONTACT_LIST","FOLLOWERS","FOLLOWING","KEYWORD_POSTERS","LIST_FOLLOWERS","CSV"]},"sourceReference":{"nullable":true,"type":"string","maxLength":2048},"previewToken":{"type":"string","minLength":1,"maxLength":256}},"required":["creatorId","sourceType","previewToken"]},"description":"Recipients exactly as dm.preview_recipients returned them."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["messageTemplate","confirmedConsent","recipients"]},"example":{"messageTemplate":"<messageTemplate>","confirmedConsent":true,"recipients":[{"creatorId":"<creatorId>","sourceType":"FROM_TWEET","previewToken":"<previewToken>"}],"dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/control-queue":{"post":{"operationId":"dm.control_queue","summary":"Pause or resume all DMs","description":"PAUSE_ALL holds every queued DM, RESUME_ALL continues, CANCEL_ALL_PENDING cancels everything not sent yet, ENABLE_SENDING turns DMs back on after a stop. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"dm_control_queue","x-xholic-cli":"xholic dm control-queue","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/control-queue \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"action\":\"PAUSE_ALL\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm control-queue --action 'PAUSE_ALL' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_control_queue\",\n  \"arguments\": {\n    \"action\": \"PAUSE_ALL\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/control-queue\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"action\": \"PAUSE_ALL\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/control-queue\",\n  {\n    \"action\": \"PAUSE_ALL\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/control-queue\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"action\": \"PAUSE_ALL\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"action\":\"PAUSE_ALL\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/control-queue\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/control-queue\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"action\":\"PAUSE_ALL\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/control-queue\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"action\":\"PAUSE_ALL\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["PAUSE_ALL","RESUME_ALL","CANCEL_ALL_PENDING","ENABLE_SENDING"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["action"]},"example":{"action":"PAUSE_ALL","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/stop-all":{"post":{"operationId":"dm.stop_all","summary":"Stop all DMs","description":"Emergency stop: cancel every pending DM and stop sending until turned back on with dm.control_queue ENABLE_SENDING. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_stop_all","x-xholic-cli":"xholic dm stop-all","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/stop-all \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm stop-all --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_stop_all\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/stop-all\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/stop-all\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/stop-all\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/stop-all\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/stop-all\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/stop-all\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/dm/campaigns":{"get":{"operationId":"dm.campaigns","summary":"DM campaigns","description":"The account's DM campaigns with status and totals, newest first.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_campaigns","x-xholic-cli":"xholic dm campaigns","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/campaigns' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm campaigns"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_campaigns\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/campaigns\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/campaigns\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/campaigns\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/campaigns\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/campaigns\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/campaigns\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["DRAFT","QUEUED","RUNNING","PAUSED","COMPLETED","CANCELLED"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/create-campaign":{"post":{"operationId":"dm.create_campaign","summary":"Create a DM campaign","description":"Create a draft DM campaign for a contact list. Then write its steps with dm.update_campaign, check it with dm.review_campaign and launch it with launch_dm_campaign. Write the messages and any per-person first lines with your own model: import the lines as a CSV column (dm.import_csv, e.g. first_line) and use [first_line]. The [ai_line] variable makes Xholic's AI write a line per recipient at launch and spends AI credits; use it only when the user asks for Xholic to write them. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"create_dm_campaign","x-xholic-cli":"xholic dm create-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/create-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm create-campaign --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"create_dm_campaign\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/create-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/create-campaign\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/create-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/create-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/create-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/create-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"contactListId":{"description":"Contact list to message.","nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"deliveryMode":{"description":"AUTOMATIC sends from the X account; ASSISTED queues them for the user to send by hand.","type":"string","enum":["AUTOMATIC","ASSISTED"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/dm/campaign":{"get":{"operationId":"dm.campaign","summary":"DM campaign details","description":"One DM campaign: steps, variants, schedule, rules and totals.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_campaign","x-xholic-cli":"xholic dm campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/campaign?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm campaign --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/campaign?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/campaign\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/campaign?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/campaign?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/campaign?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"example":"<id>","description":"DM campaign id."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/update-campaign":{"post":{"operationId":"dm.update_campaign","summary":"Edit a DM campaign","description":"Replace a draft campaign's settings: send the whole draft (read it with dm.campaign first). Steps are the first message plus up to 2 follow-ups, each with up to three A/B variants. Write the messages and any per-person first lines with your own model: import the lines as a CSV column (dm.import_csv, e.g. first_line) and use [first_line]. The [ai_line] variable makes Xholic's AI write a line per recipient at launch and spends AI credits; use it only when the user asks for Xholic to write them. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_update_campaign","x-xholic-cli":"xholic dm update-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/update-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"name\":\"Example\",\"deliveryMode\":\"AUTOMATIC\",\"contactListId\":\"<contactListId>\",\"steps\":[{\"position\":1,\"delayDays\":1,\"variants\":[\"<variant>\"]}],\"schedule\":{\"timezone\":\"America/New_York\",\"sendDays\":1,\"windowStartMinutes\":1,\"windowEndMinutes\":1,\"dailyLimit\":1,\"rampStart\":1,\"rampStep\":1,\"minGapSeconds\":75,\"maxGapSeconds\":75,\"startsAt\":\"2026-11-03T09:00:00Z\"},\"rules\":{},\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm update-campaign --id '<id>' --name 'Example' --delivery-mode 'AUTOMATIC' --contact-list-id '<contactListId>' --steps '[{\"position\":1,\"delayDays\":1,\"variants\":[\"<variant>\"]}]' --schedule '{\"timezone\":\"America/New_York\",\"sendDays\":1,\"windowStartMinutes\":1,\"windowEndMinutes\":1,\"dailyLimit\":1,\"rampStart\":1,\"rampStep\":1,\"minGapSeconds\":75,\"maxGapSeconds\":75,\"startsAt\":\"2026-11-03T09:00:00Z\"}' --rules '{}' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_update_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"deliveryMode\": \"AUTOMATIC\",\n    \"contactListId\": \"<contactListId>\",\n    \"steps\": [\n      {\n        \"position\": 1,\n        \"delayDays\": 1,\n        \"variants\": [\n          \"<variant>\"\n        ]\n      }\n    ],\n    \"schedule\": {\n      \"timezone\": \"America/New_York\",\n      \"sendDays\": 1,\n      \"windowStartMinutes\": 1,\n      \"windowEndMinutes\": 1,\n      \"dailyLimit\": 1,\n      \"rampStart\": 1,\n      \"rampStep\": 1,\n      \"minGapSeconds\": 75,\n      \"maxGapSeconds\": 75,\n      \"startsAt\": \"2026-11-03T09:00:00Z\"\n    },\n    \"rules\": {},\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/update-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"deliveryMode\": \"AUTOMATIC\",\n    \"contactListId\": \"<contactListId>\",\n    \"steps\": [\n      {\n        \"position\": 1,\n        \"delayDays\": 1,\n        \"variants\": [\n          \"<variant>\"\n        ]\n      }\n    ],\n    \"schedule\": {\n      \"timezone\": \"America/New_York\",\n      \"sendDays\": 1,\n      \"windowStartMinutes\": 1,\n      \"windowEndMinutes\": 1,\n      \"dailyLimit\": 1,\n      \"rampStart\": 1,\n      \"rampStep\": 1,\n      \"minGapSeconds\": 75,\n      \"maxGapSeconds\": 75,\n      \"startsAt\": \"2026-11-03T09:00:00Z\"\n    },\n    \"rules\": {},\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/update-campaign\",\n  {\n    \"id\": \"<id>\",\n    \"name\": \"Example\",\n    \"deliveryMode\": \"AUTOMATIC\",\n    \"contactListId\": \"<contactListId>\",\n    \"steps\": [\n      {\n        \"position\": 1,\n        \"delayDays\": 1,\n        \"variants\": [\n          \"<variant>\"\n        ]\n      }\n    ],\n    \"schedule\": {\n      \"timezone\": \"America/New_York\",\n      \"sendDays\": 1,\n      \"windowStartMinutes\": 1,\n      \"windowEndMinutes\": 1,\n      \"dailyLimit\": 1,\n      \"rampStart\": 1,\n      \"rampStep\": 1,\n      \"minGapSeconds\": 75,\n      \"maxGapSeconds\": 75,\n      \"startsAt\": \"2026-11-03T09:00:00Z\"\n    },\n    \"rules\": {},\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/update-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"name\": \"Example\",\n        \"deliveryMode\": \"AUTOMATIC\",\n        \"contactListId\": \"<contactListId>\",\n        \"steps\": [\n            {\n                \"position\": 1,\n                \"delayDays\": 1,\n                \"variants\": [\n                    \"<variant>\"\n                ]\n            }\n        ],\n        \"schedule\": {\n            \"timezone\": \"America/New_York\",\n            \"sendDays\": 1,\n            \"windowStartMinutes\": 1,\n            \"windowEndMinutes\": 1,\n            \"dailyLimit\": 1,\n            \"rampStart\": 1,\n            \"rampStep\": 1,\n            \"minGapSeconds\": 75,\n            \"maxGapSeconds\": 75,\n            \"startsAt\": \"2026-11-03T09:00:00Z\"\n        },\n        \"rules\": {},\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"name\":\"Example\",\"deliveryMode\":\"AUTOMATIC\",\"contactListId\":\"<contactListId>\",\"steps\":[{\"position\":1,\"delayDays\":1,\"variants\":[\"<variant>\"]}],\"schedule\":{\"timezone\":\"America/New_York\",\"sendDays\":1,\"windowStartMinutes\":1,\"windowEndMinutes\":1,\"dailyLimit\":1,\"rampStart\":1,\"rampStep\":1,\"minGapSeconds\":75,\"maxGapSeconds\":75,\"startsAt\":\"2026-11-03T09:00:00Z\"},\"rules\":{},\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/update-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/update-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"name\":\"Example\",\"deliveryMode\":\"AUTOMATIC\",\"contactListId\":\"<contactListId>\",\"steps\":[{\"position\":1,\"delayDays\":1,\"variants\":[\"<variant>\"]}],\"schedule\":{\"timezone\":\"America/New_York\",\"sendDays\":1,\"windowStartMinutes\":1,\"windowEndMinutes\":1,\"dailyLimit\":1,\"rampStart\":1,\"rampStep\":1,\"minGapSeconds\":75,\"maxGapSeconds\":75,\"startsAt\":\"2026-11-03T09:00:00Z\"},\"rules\":{},\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/update-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"name\":\"Example\",\"deliveryMode\":\"AUTOMATIC\",\"contactListId\":\"<contactListId>\",\"steps\":[{\"position\":1,\"delayDays\":1,\"variants\":[\"<variant>\"]}],\"schedule\":{\"timezone\":\"America/New_York\",\"sendDays\":1,\"windowStartMinutes\":1,\"windowEndMinutes\":1,\"dailyLimit\":1,\"rampStart\":1,\"rampStep\":1,\"minGapSeconds\":75,\"maxGapSeconds\":75,\"startsAt\":\"2026-11-03T09:00:00Z\"},\"rules\":{},\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"name":{"type":"string","minLength":1,"maxLength":80},"deliveryMode":{"type":"string","enum":["AUTOMATIC","ASSISTED"]},"contactListId":{"nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"steps":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"object","properties":{"position":{"type":"integer","minimum":1,"maximum":3},"delayDays":{"type":"integer","minimum":0,"maximum":30},"variants":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","enum":["A","B","C"]},"template":{"type":"string","minLength":1,"maxLength":5000},"weight":{"default":1,"type":"integer","minimum":1,"maximum":10}},"required":["label","template"]}}},"required":["position","delayDays","variants"]},"description":"In order from position 1. Step 1 has delayDays 0; follow-ups wait at least a day. Each variant's template is the message: [first], [name], list fields like [first_line], {Hi|Hey} spintax."},"schedule":{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":64},"sendDays":{"type":"integer","minimum":1,"maximum":127},"windowStartMinutes":{"type":"integer","minimum":0,"maximum":1439},"windowEndMinutes":{"type":"integer","minimum":1,"maximum":1440},"dailyLimit":{"type":"integer","minimum":1,"maximum":100},"rampStart":{"nullable":true,"type":"integer","minimum":1,"maximum":100},"rampStep":{"nullable":true,"type":"integer","minimum":1,"maximum":50},"minGapSeconds":{"type":"integer","minimum":75,"maximum":3600},"maxGapSeconds":{"type":"integer","minimum":75,"maximum":3600},"startsAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["timezone","sendDays","windowStartMinutes","windowEndMinutes","dailyLimit","rampStart","rampStep","minGapSeconds","maxGapSeconds","startsAt"]},"rules":{"type":"object","properties":{"recontactAfterDays":{"default":null,"anyOf":[{"type":"number","enum":[30]},{"type":"number","enum":[60]},{"type":"number","enum":[90]},{"type":"string","nullable":true,"enum":[null]}]},"excludeCampaignIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"excludeListIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"skipFollowers":{"default":false,"type":"boolean"},"skipFollowing":{"default":false,"type":"boolean"},"skipExistingConversation":{"default":true,"type":"boolean"}}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","name","deliveryMode","contactListId","steps","schedule","rules"]},"example":{"id":"<id>","name":"Example","deliveryMode":"AUTOMATIC","contactListId":"<contactListId>","steps":[{"position":1,"delayDays":1,"variants":["<variant>"]}],"schedule":{"timezone":"America/New_York","sendDays":1,"windowStartMinutes":1,"windowEndMinutes":1,"dailyLimit":1,"rampStart":1,"rampStep":1,"minGapSeconds":75,"maxGapSeconds":75,"startsAt":"2026-11-03T09:00:00Z"},"rules":{},"dryRun":true}}}}}},"/dm/control-campaign":{"post":{"operationId":"dm.control_campaign","summary":"Pause or resume a campaign","description":"PAUSE or RESUME a running campaign, or CANCEL_PENDING to cancel its unsent messages. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"dm_control_campaign","x-xholic-cli":"xholic dm control-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/control-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"action\":\"PAUSE\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm control-campaign --id '<id>' --action 'PAUSE' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_control_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"action\": \"PAUSE\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/control-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"action\": \"PAUSE\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/control-campaign\",\n  {\n    \"id\": \"<id>\",\n    \"action\": \"PAUSE\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/control-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"action\": \"PAUSE\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"action\":\"PAUSE\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/control-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/control-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"action\":\"PAUSE\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/control-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"action\":\"PAUSE\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"action":{"type":"string","enum":["PAUSE","RESUME","CANCEL_PENDING"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","action"]},"example":{"id":"<id>","action":"PAUSE","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/delete-campaign":{"post":{"operationId":"dm.delete_campaign","summary":"Delete a draft campaign","description":"Delete a DM campaign that hasn't launched. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_delete_campaign","x-xholic-cli":"xholic dm delete-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/delete-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm delete-campaign --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_delete_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/delete-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/delete-campaign\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/delete-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/delete-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/delete-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/delete-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/review-campaign":{"get":{"operationId":"dm.review_campaign","summary":"Check a campaign before launch","description":"Check a draft campaign before launch: who can be messaged, who is skipped and why, missing variables, and the outreach guidelines the user must accept. Show the guidelines to the user before launching.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_review_campaign","x-xholic-cli":"xholic dm review-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/review-campaign?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm review-campaign --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_review_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/review-campaign?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/review-campaign\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/review-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/review-campaign?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/review-campaign?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/review-campaign?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"example":"<id>","description":"DM campaign id."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/launch-campaign":{"post":{"operationId":"dm.launch_campaign","summary":"Launch a DM campaign","description":"Launch a reviewed campaign: its messages start sending on its schedule. Run dm.review_campaign first, show the user the outreach guidelines, and pass confirmedConsent true only after they accept. If a template uses [ai_line], launching reserves AI credits for each recipient and needs confirmCredits. Call it only when the user asked for this in the conversation; never on your own initiative.\n\nUses Xholic AI credits (up to about 0). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"launch_dm_campaign","x-xholic-cli":"xholic dm launch-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/launch-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"confirmedConsent\":false,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm launch-campaign --id '<id>' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"launch_dm_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"confirmedConsent\": false,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/launch-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"confirmedConsent\": false,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/launch-campaign\",\n  {\n    \"id\": \"<id>\",\n    \"confirmedConsent\": false,\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/launch-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"confirmedConsent\": False,\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"confirmedConsent\":false,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/launch-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/launch-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"confirmedConsent\":false,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/launch-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"confirmedConsent\":false,\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"confirmedConsent":{"type":"boolean","description":"The user accepted the cold-outreach guidelines shown by dm.review_campaign."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["id","confirmedConsent"]},"example":{"id":"<id>","confirmedConsent":false,"dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/preview-campaign":{"post":{"operationId":"dm.preview_campaign","summary":"Preview campaign messages","description":"Render a campaign step's message for a few recipients exactly as it will be sent. With generateAiLine true, Xholic's AI writes the missing [ai_line] first lines and charges per line: quote first, show it to the user, and pass confirmCredits after they agree. Without it, previews are free.\n\nUses Xholic AI credits (up to about 10). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_preview_campaign","x-xholic-cli":"xholic dm preview-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/preview-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm preview-campaign --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_preview_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/preview-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/preview-campaign\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/preview-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/preview-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/preview-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/preview-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991},"limit":{"type":"integer","minimum":1,"maximum":5},"stepPosition":{"type":"integer","minimum":1,"maximum":3},"variantLabel":{"nullable":true,"type":"string","enum":["A","B","C"]},"generateAiLine":{"description":"Write missing [ai_line] first lines with Xholic's AI (spends credits).","type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/duplicate-campaign":{"post":{"operationId":"dm.duplicate_campaign","summary":"Duplicate a campaign","description":"Copy a campaign's steps and settings into a new draft. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_duplicate_campaign","x-xholic-cli":"xholic dm duplicate-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/duplicate-campaign \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm duplicate-campaign --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_duplicate_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/duplicate-campaign\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/duplicate-campaign\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/duplicate-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/duplicate-campaign\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/duplicate-campaign\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/duplicate-campaign\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/campaign-recipients":{"get":{"operationId":"dm.campaign_recipients","summary":"Campaign recipients","description":"A campaign's recipients with each one's status, step and reply.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_campaign_recipients","x-xholic-cli":"xholic dm campaign-recipients","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/campaign-recipients?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm campaign-recipients --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_campaign_recipients\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/campaign-recipients?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/campaign-recipients\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/campaign-recipients\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/campaign-recipients?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/campaign-recipients?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/campaign-recipients?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"example":"<id>","description":"DM campaign id."},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","SENDING","SENT","SKIPPED","FAILED","DELIVERY_UNKNOWN","CANCELLED"]}},{"name":"step","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":3}},{"name":"q","in":"query","required":false,"schema":{"description":"Search by name or handle.","type":"string","maxLength":50},"description":"Search by name or handle."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/campaign-stats":{"get":{"operationId":"dm.campaign_stats","summary":"DM campaign results","description":"How a campaign is doing: sent, replied, interested and booked, by step and A/B variant.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_dm_campaign_stats","x-xholic-cli":"xholic dm campaign-stats","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/campaign-stats?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm campaign-stats --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_dm_campaign_stats\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/campaign-stats?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/campaign-stats\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/campaign-stats\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/campaign-stats?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/campaign-stats?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/campaign-stats?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"example":"<id>","description":"DM campaign id."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/export-campaign":{"get":{"operationId":"dm.export_campaign","summary":"Export a campaign","description":"A campaign's recipients and results as CSV.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_export_campaign","x-xholic-cli":"xholic dm export-campaign","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/export-campaign?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm export-campaign --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_export_campaign\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/export-campaign?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/export-campaign\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/export-campaign\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/export-campaign?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/export-campaign?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/export-campaign?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"DM campaign id."},"example":"<id>","description":"DM campaign id."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/today":{"get":{"operationId":"dm.today","summary":"Assisted DMs for today","description":"Messages from ASSISTED campaigns ready for the user to send by hand today, with the rendered text and a link to each person's DMs.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_today","x-xholic-cli":"xholic dm today","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/today' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm today"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_today\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/today\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/today\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/today\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/today\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/today\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/today\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/mark-assisted-sent":{"post":{"operationId":"dm.mark_assisted_sent","summary":"Mark an assisted DM sent","description":"Record that the user sent an assisted DM by hand. Undo works for a minute. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_mark_assisted_sent","x-xholic-cli":"xholic dm mark-assisted-sent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/mark-assisted-sent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm mark-assisted-sent --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_mark_assisted_sent\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/mark-assisted-sent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/mark-assisted-sent\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/mark-assisted-sent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/mark-assisted-sent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/mark-assisted-sent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/mark-assisted-sent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Campaign recipient id from dm.today or dm.campaign_recipients."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/undo-assisted-sent":{"post":{"operationId":"dm.undo_assisted_sent","summary":"Undo marking an assisted DM sent","description":"Put an assisted DM back in today's queue within a minute of marking it sent.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_undo_assisted_sent","x-xholic-cli":"xholic dm undo-assisted-sent","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/undo-assisted-sent \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm undo-assisted-sent --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_undo_assisted_sent\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/undo-assisted-sent\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/undo-assisted-sent\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/undo-assisted-sent\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/undo-assisted-sent\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/undo-assisted-sent\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/undo-assisted-sent\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Campaign recipient id from dm.today or dm.campaign_recipients."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/skip-recipient":{"post":{"operationId":"dm.skip_recipient","summary":"Skip a recipient","description":"Skip one person in a campaign so they aren't messaged. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_skip_recipient","x-xholic-cli":"xholic dm skip-recipient","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/skip-recipient \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm skip-recipient --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_skip_recipient\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/skip-recipient\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/skip-recipient\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/skip-recipient\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/skip-recipient\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/skip-recipient\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/skip-recipient\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Campaign recipient id from dm.today or dm.campaign_recipients."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/cancel-recipient":{"post":{"operationId":"dm.cancel_recipient","summary":"Cancel a pending DM","description":"Cancel a DM that is queued but not sent yet. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_cancel_recipient","x-xholic-cli":"xholic dm cancel-recipient","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/cancel-recipient \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm cancel-recipient --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_cancel_recipient\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/cancel-recipient\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/cancel-recipient\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/cancel-recipient\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/cancel-recipient\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/cancel-recipient\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/cancel-recipient\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Campaign recipient id from dm.today or dm.campaign_recipients."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/inbox":{"get":{"operationId":"dm.inbox","summary":"DM inbox","description":"DM conversations with replies, newest first, with each person's lead status. Filter by lead status, campaign or unread.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"get_dm_inbox","x-xholic-cli":"xholic dm inbox","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/inbox' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm inbox"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"get_dm_inbox\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/inbox\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/inbox\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/inbox\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/inbox\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/inbox\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/inbox\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"leadStatus","in":"query","required":false,"schema":{"type":"string","enum":["NEW","REPLIED","INTERESTED","NOT_INTERESTED","MEETING_BOOKED","DO_NOT_CONTACT"]}},{"name":"campaignId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"unread","in":"query","required":false,"schema":{"description":"\"true\" for unread conversations only.","type":"string","enum":["true","false"]},"description":"\"true\" for unread conversations only."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/thread":{"get":{"operationId":"dm.thread","summary":"DM conversation","description":"The full DM conversation with one person.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_thread","x-xholic-cli":"xholic dm thread","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/thread?creatorId=%3CcreatorId%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm thread --creator-id '<creatorId>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_thread\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/thread?creatorId=%3CcreatorId%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/thread\", {\n  params: {\n    \"creatorId\": \"<creatorId>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/thread\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"creatorId\": \"<creatorId>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/thread?creatorId=%3CcreatorId%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/thread?creatorId=%3CcreatorId%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/thread?creatorId=%3CcreatorId%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"creatorId","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"example":"<creatorId>","description":"The person's numeric X user id."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/update-conversation":{"post":{"operationId":"dm.update_conversation","summary":"Update a DM conversation","description":"Set a conversation's lead status (e.g. INTERESTED, MEETING_BOOKED, DO_NOT_CONTACT) or mark it read or unread. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_update_conversation","x-xholic-cli":"xholic dm update-conversation","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/update-conversation \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm update-conversation --creator-id '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_update_conversation\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/update-conversation\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/update-conversation\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/update-conversation\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/update-conversation\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/update-conversation\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/update-conversation\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"leadStatus":{"type":"string","enum":["NEW","REPLIED","INTERESTED","NOT_INTERESTED","MEETING_BOOKED","DO_NOT_CONTACT"]},"unread":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorId"]},"example":{"creatorId":"<creatorId>","dryRun":true}}}}}},"/dm/reply":{"post":{"operationId":"dm.reply","summary":"Reply to a DM","description":"Send a DM reply in a conversation from the user's X account. Write the reply yourself from the thread (dm.thread) in the user's voice. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"reply_to_dm","x-xholic-cli":"xholic dm reply","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/reply \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm reply --creator-id '<creatorId>' --text 'Shipping the API today' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"reply_to_dm\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/reply\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/reply\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"text\": \"Shipping the API today\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/reply\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"text\": \"Shipping the API today\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/reply\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/reply\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/reply\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"text\":\"Shipping the API today\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"text":{"type":"string","minLength":1,"maxLength":5000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorId","text"]},"example":{"creatorId":"<creatorId>","text":"Shipping the API today","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/suggest-reply":{"post":{"operationId":"dm.suggest_reply","summary":"Suggest a DM reply with Xholic","description":"Have Xholic's AI suggest a reply in a DM conversation. Use only when the user asks for Xholic to write it; otherwise write the reply yourself. Spends Xholic AI credits: quote first, show it to the user, and pass confirmCredits after they agree. Nothing is sent.\n\nUses Xholic AI credits (up to about 8). The first call returns CREDITS_CONFIRMATION_REQUIRED with a quote; after the user agrees, call again with confirmCredits and the quote's quoteId.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_suggest_reply","x-xholic-cli":"xholic dm suggest-reply","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/suggest-reply \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm suggest-reply --creator-id '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_suggest_reply\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/suggest-reply\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/suggest-reply\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/suggest-reply\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/suggest-reply\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/suggest-reply\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/suggest-reply\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200},"confirmCredits":{"description":"Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.","type":"number","minimum":0,"maximum":100000},"quoteId":{"description":"The quoteId from the quote the user agreed to. Send it with confirmCredits.","type":"string","minLength":8,"maxLength":100}},"required":["creatorId"]},"example":{"creatorId":"<creatorId>","dryRun":true}}}}}},"/dm/lists":{"get":{"operationId":"dm.lists","summary":"DM lists","description":"Contact lists available for DM campaigns, with sizes, custom fields and how many can be messaged.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_lists","x-xholic-cli":"xholic dm lists","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/lists' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm lists"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_lists\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/lists\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/lists\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/lists\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/lists\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/lists\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/lists\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/estimate-import":{"get":{"operationId":"dm.estimate_import","summary":"Estimate a lead import","description":"Estimate how many profiles an import (followers, following, keyword posters, X list, post engagers or handles) would bring in and what it uses of the plan's import pool. Imports nothing.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_estimate_import","x-xholic-cli":"xholic dm estimate-import","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/estimate-import?source=%7B%22kind%22%3A%22FOLLOWERS%22%7D&maxProfiles=1' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm estimate-import --source '{\"kind\":\"FOLLOWERS\"}' --max-profiles 1"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_estimate_import\",\n  \"arguments\": {\n    \"source\": {\n      \"kind\": \"FOLLOWERS\"\n    },\n    \"maxProfiles\": 1\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/estimate-import?source=%7B%22kind%22%3A%22FOLLOWERS%22%7D&maxProfiles=1\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/estimate-import\", {\n  params: {\n    \"source\": {\n      \"kind\": \"FOLLOWERS\"\n    },\n    \"maxProfiles\": 1\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/estimate-import\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"source\": {\n            \"kind\": \"FOLLOWERS\"\n        },\n        \"maxProfiles\": 1\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/estimate-import?source=%7B%22kind%22%3A%22FOLLOWERS%22%7D&maxProfiles=1\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/estimate-import?source=%7B%22kind%22%3A%22FOLLOWERS%22%7D&maxProfiles=1\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/estimate-import?source=%7B%22kind%22%3A%22FOLLOWERS%22%7D&maxProfiles=1\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"source","in":"query","required":true,"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["FOLLOWERS","FOLLOWING","KEYWORD_POSTERS","X_LIST","LIST_FOLLOWERS","POST_ENGAGERS","HANDLES"]}},"required":["kind"],"additionalProperties":{},"description":"Who to import. FOLLOWERS/FOLLOWING {handle}; KEYWORD_POSTERS {query, days?, language?, excludeHandles?}; X_LIST/LIST_FOLLOWERS {listUrl}; POST_ENGAGERS {tweetUrl, includeReplies?, includeReposts?, keyword?}; HANDLES {handles}."},"example":{"kind":"FOLLOWERS"},"description":"Who to import. FOLLOWERS/FOLLOWING {handle}; KEYWORD_POSTERS {query, days?, language?, excludeHandles?}; X_LIST/LIST_FOLLOWERS {listUrl}; POST_ENGAGERS {tweetUrl, includeReplies?, includeReposts?, keyword?}; HANDLES {handles}."},{"name":"filters","in":"query","required":false,"schema":{"description":"Optional filters: followersMin, followersMax, bioIncludes, bioExcludes, locationIncludes, verified (any|only|exclude), dmsOpenOnly, excludeProtected, excludeAutomated, minAccountAgeDays.","type":"object","properties":{},"additionalProperties":{}},"description":"Optional filters: followersMin, followersMax, bioIncludes, bioExcludes, locationIncludes, verified (any|only|exclude), dmsOpenOnly, excludeProtected, excludeAutomated, minAccountAgeDays."},{"name":"maxProfiles","in":"query","required":true,"schema":{"type":"integer","minimum":1,"maximum":15000},"example":1},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/queue-import":{"post":{"operationId":"dm.queue_import","summary":"Import leads for DMs","description":"Queue an import of X profiles into a contact list for DM campaigns. Runs in the background and uses the plan's import pool; estimate it first with dm.estimate_import. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_queue_import","x-xholic-cli":"xholic dm queue-import","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/queue-import \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"source\":{\"kind\":\"FOLLOWERS\"},\"maxProfiles\":1,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm queue-import --source '{\"kind\":\"FOLLOWERS\"}' --max-profiles 1 --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_queue_import\",\n  \"arguments\": {\n    \"source\": {\n      \"kind\": \"FOLLOWERS\"\n    },\n    \"maxProfiles\": 1,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/queue-import\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"source\": {\n      \"kind\": \"FOLLOWERS\"\n    },\n    \"maxProfiles\": 1,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/queue-import\",\n  {\n    \"source\": {\n      \"kind\": \"FOLLOWERS\"\n    },\n    \"maxProfiles\": 1,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/queue-import\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"source\": {\n            \"kind\": \"FOLLOWERS\"\n        },\n        \"maxProfiles\": 1,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"source\":{\"kind\":\"FOLLOWERS\"},\"maxProfiles\":1,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/queue-import\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/queue-import\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"source\":{\"kind\":\"FOLLOWERS\"},\"maxProfiles\":1,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/queue-import\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"source\":{\"kind\":\"FOLLOWERS\"},\"maxProfiles\":1,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"object","properties":{"kind":{"type":"string","enum":["FOLLOWERS","FOLLOWING","KEYWORD_POSTERS","X_LIST","LIST_FOLLOWERS","POST_ENGAGERS","HANDLES"]}},"required":["kind"],"additionalProperties":{},"description":"Who to import. FOLLOWERS/FOLLOWING {handle}; KEYWORD_POSTERS {query, days?, language?, excludeHandles?}; X_LIST/LIST_FOLLOWERS {listUrl}; POST_ENGAGERS {tweetUrl, includeReplies?, includeReposts?, keyword?}; HANDLES {handles}."},"filters":{"description":"Optional filters: followersMin, followersMax, bioIncludes, bioExcludes, locationIncludes, verified (any|only|exclude), dmsOpenOnly, excludeProtected, excludeAutomated, minAccountAgeDays.","type":"object","properties":{},"additionalProperties":{}},"maxProfiles":{"type":"integer","minimum":1,"maximum":15000},"listId":{"description":"Contact list to import into.","nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"newListName":{"description":"Name for a new list instead. Pass exactly one of listId or newListName.","nullable":true,"type":"string","minLength":1,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["source","maxProfiles"]},"example":{"source":{"kind":"FOLLOWERS"},"maxProfiles":1,"dryRun":true}}}}}},"/dm/import-csv":{"post":{"operationId":"dm.import_csv","summary":"Import a CSV of leads","description":"Import handles and custom fields from CSV text (up to 200 KB) into a contact list. This is how you hand Xholic first lines you wrote: add a column such as first_line and use [first_line] in the campaign template. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_import_csv","x-xholic-cli":"xholic dm import-csv","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/import-csv \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"csv\":\"<csv>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm import-csv --csv '<csv>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_import_csv\",\n  \"arguments\": {\n    \"csv\": \"<csv>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/import-csv\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"csv\": \"<csv>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/import-csv\",\n  {\n    \"csv\": \"<csv>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/import-csv\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"csv\": \"<csv>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"csv\":\"<csv>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/import-csv\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/import-csv\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"csv\":\"<csv>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/import-csv\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"csv\":\"<csv>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"description":"The CSV text, with a header row."},"handleColumn":{"description":"Header of the column holding X handles; detected when left out.","nullable":true,"type":"string","maxLength":80},"fieldMap":{"description":"CSV header to field key (lowercase, e.g. first_line), or null to ignore a column.","type":"object","additionalProperties":{"nullable":true,"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$"}},"listId":{"description":"Contact list to import into.","nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"newListName":{"description":"Name for a new list instead. Pass exactly one of listId or newListName.","nullable":true,"type":"string","minLength":1,"maxLength":80},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["csv"]},"example":{"csv":"<csv>","dryRun":true}}}}}},"/dm/imports":{"get":{"operationId":"dm.imports","summary":"DM lead imports","description":"Lead imports with their progress, optionally for one list.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_imports","x-xholic-cli":"xholic dm imports","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/imports' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm imports"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_imports\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/imports\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/imports\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/imports\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/imports\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/imports\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/imports\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"listId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/cancel-import":{"post":{"operationId":"dm.cancel_import","summary":"Stop a lead import","description":"Stop a running lead import. Profiles already imported stay.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_cancel_import","x-xholic-cli":"xholic dm cancel-import","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/cancel-import \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm cancel-import --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_cancel_import\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/cancel-import\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/cancel-import\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/cancel-import\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/cancel-import\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/cancel-import\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/cancel-import\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Import id from dm.imports."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/dm/settings":{"get":{"operationId":"dm.settings","summary":"DM settings","description":"Default delivery mode, schedule and rules for new campaigns, the assisted daily limit and opt-out phrases.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_settings","x-xholic-cli":"xholic dm settings","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/settings' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm settings"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_settings\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/settings\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/settings\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/settings\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/settings\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/settings\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/settings\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/update-settings":{"post":{"operationId":"dm.update_settings","summary":"Change DM settings","description":"Replace the DM settings: send all of them (read them with dm.settings first). Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_update_settings","x-xholic-cli":"xholic dm update-settings","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/update-settings \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"defaults\":{},\"assistedDailyLimit\":1,\"optOutPhrases\":[\"<optOutPhrase>\"],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm update-settings --defaults '{}' --assisted-daily-limit 1 --opt-out-phrases '<optOutPhrase>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_update_settings\",\n  \"arguments\": {\n    \"defaults\": {},\n    \"assistedDailyLimit\": 1,\n    \"optOutPhrases\": [\n      \"<optOutPhrase>\"\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/update-settings\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"defaults\": {},\n    \"assistedDailyLimit\": 1,\n    \"optOutPhrases\": [\n      \"<optOutPhrase>\"\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/update-settings\",\n  {\n    \"defaults\": {},\n    \"assistedDailyLimit\": 1,\n    \"optOutPhrases\": [\n      \"<optOutPhrase>\"\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/update-settings\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"defaults\": {},\n        \"assistedDailyLimit\": 1,\n        \"optOutPhrases\": [\n            \"<optOutPhrase>\"\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"defaults\":{},\"assistedDailyLimit\":1,\"optOutPhrases\":[\"<optOutPhrase>\"],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/update-settings\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/update-settings\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"defaults\":{},\"assistedDailyLimit\":1,\"optOutPhrases\":[\"<optOutPhrase>\"],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/update-settings\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"defaults\":{},\"assistedDailyLimit\":1,\"optOutPhrases\":[\"<optOutPhrase>\"],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"defaults":{"type":"object","properties":{"deliveryMode":{"default":"AUTOMATIC","type":"string","enum":["AUTOMATIC","ASSISTED"]},"schedule":{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":64},"sendDays":{"type":"integer","minimum":1,"maximum":127},"windowStartMinutes":{"type":"integer","minimum":0,"maximum":1439},"windowEndMinutes":{"type":"integer","minimum":1,"maximum":1440},"dailyLimit":{"type":"integer","minimum":1,"maximum":100},"rampStart":{"nullable":true,"type":"integer","minimum":1,"maximum":100},"rampStep":{"nullable":true,"type":"integer","minimum":1,"maximum":50},"minGapSeconds":{"type":"integer","minimum":75,"maximum":3600},"maxGapSeconds":{"type":"integer","minimum":75,"maximum":3600},"startsAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["timezone","sendDays","windowStartMinutes","windowEndMinutes","dailyLimit","rampStart","rampStep","minGapSeconds","maxGapSeconds","startsAt"]},"rules":{"default":{"recontactAfterDays":null,"excludeCampaignIds":[],"excludeListIds":[],"skipFollowers":false,"skipFollowing":false,"skipExistingConversation":true},"type":"object","properties":{"recontactAfterDays":{"default":null,"anyOf":[{"type":"number","enum":[30]},{"type":"number","enum":[60]},{"type":"number","enum":[90]},{"type":"string","nullable":true,"enum":[null]}]},"excludeCampaignIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"excludeListIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"skipFollowers":{"default":false,"type":"boolean"},"skipFollowing":{"default":false,"type":"boolean"},"skipExistingConversation":{"default":true,"type":"boolean"}}}}},"assistedDailyLimit":{"type":"integer","minimum":1,"maximum":100},"optOutPhrases":{"maxItems":20,"type":"array","items":{"type":"string","minLength":2,"maxLength":40},"description":"Replies containing one of these stop all messages to that person."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["defaults","assistedDailyLimit","optOutPhrases"]},"example":{"defaults":{},"assistedDailyLimit":1,"optOutPhrases":["<optOutPhrase>"],"dryRun":true}}}}}},"/dm/suppressions":{"get":{"operationId":"dm.suppressions","summary":"Do-not-message list","description":"People the account will never DM.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_suppressions","x-xholic-cli":"xholic dm suppressions","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/suppressions' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm suppressions"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_suppressions\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/suppressions\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/suppressions\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/suppressions\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/suppressions\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/suppressions\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/suppressions\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"q","in":"query","required":false,"schema":{"description":"Search by name or handle.","type":"string","maxLength":50},"description":"Search by name or handle."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/suppress":{"post":{"operationId":"dm.suppress","summary":"Never DM someone","description":"Add a person to the do-not-message list and cancel their pending DMs. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_suppress","x-xholic-cli":"xholic dm suppress","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/suppress \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm suppress --creator-id '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_suppress\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/suppress\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/suppress\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/suppress\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/suppress\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/suppress\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/suppress\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"reason":{"nullable":true,"type":"string","maxLength":1000},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorId"]},"example":{"creatorId":"<creatorId>","dryRun":true}}}}}},"/dm/bulk-suppress":{"post":{"operationId":"dm.bulk_suppress","summary":"Never DM these people","description":"Add many handles to the do-not-message list at once and cancel their pending DMs. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_bulk_suppress","x-xholic-cli":"xholic dm bulk-suppress","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/bulk-suppress \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"handles\":[\"@founder\"],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm bulk-suppress --handles '@founder' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_bulk_suppress\",\n  \"arguments\": {\n    \"handles\": [\n      \"@founder\"\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/bulk-suppress\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"handles\": [\n      \"@founder\"\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/bulk-suppress\",\n  {\n    \"handles\": [\n      \"@founder\"\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/bulk-suppress\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"handles\": [\n            \"@founder\"\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"handles\":[\"@founder\"],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/bulk-suppress\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/bulk-suppress\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"handles\":[\"@founder\"],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/bulk-suppress\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"handles\":[\"@founder\"],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"handles":{"minItems":1,"maxItems":5000,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"description":"X handle like @name, or a link to their profile."}},"reason":{"nullable":true,"type":"string","maxLength":200},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["handles"]},"example":{"handles":["@founder"],"dryRun":true}}}}}},"/dm/unsuppress":{"post":{"operationId":"dm.unsuppress","summary":"Allow DMs to someone again","description":"Remove a person from the do-not-message list. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_unsuppress","x-xholic-cli":"xholic dm unsuppress","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/unsuppress \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm unsuppress --creator-id '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_unsuppress\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/unsuppress\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/unsuppress\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/unsuppress\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/unsuppress\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/unsuppress\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/unsuppress\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","pattern":"^\\d{1,24}$","description":"The person's numeric X user id."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorId"]},"example":{"creatorId":"<creatorId>","dryRun":true}}}}}},"/dm/inbound-rules":{"get":{"operationId":"dm.inbound_rules","summary":"Keyword auto-replies","description":"Keyword rules that DM people automatically when they message or reply with a word like GUIDE.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"dm_inbound_rules","x-xholic-cli":"xholic dm inbound-rules","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/dm/inbound-rules' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic dm inbound-rules"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_inbound_rules\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/inbound-rules\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/dm/inbound-rules\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/dm/inbound-rules\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/dm/inbound-rules\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/inbound-rules\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/inbound-rules\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/dm/create-inbound-rule":{"post":{"operationId":"dm.create_inbound_rule","summary":"Add a keyword auto-reply","description":"Add a rule that automatically DMs replyTemplate to anyone who sends the keyword. Write the reply yourself. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"dm_create_inbound_rule","x-xholic-cli":"xholic dm create-inbound-rule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/create-inbound-rule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm create-inbound-rule --keyword '<keyword>' --reply-template '<replyTemplate>' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_create_inbound_rule\",\n  \"arguments\": {\n    \"keyword\": \"<keyword>\",\n    \"replyTemplate\": \"<replyTemplate>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/create-inbound-rule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"keyword\": \"<keyword>\",\n    \"replyTemplate\": \"<replyTemplate>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/create-inbound-rule\",\n  {\n    \"keyword\": \"<keyword>\",\n    \"replyTemplate\": \"<replyTemplate>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/create-inbound-rule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"keyword\": \"<keyword>\",\n        \"replyTemplate\": \"<replyTemplate>\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/create-inbound-rule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/create-inbound-rule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/create-inbound-rule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyword":{"type":"string","minLength":1,"maxLength":40,"description":"A single word, like GUIDE."},"replyTemplate":{"type":"string","minLength":1,"maxLength":5000,"description":"The message. Variables: [first], [name], [handle], [location], [followers], list fields such as [first_line], with optional fallbacks like [first|there]; spintax like {Hi|Hey}. Write it yourself in the user's voice."},"active":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["keyword","replyTemplate"]},"example":{"keyword":"<keyword>","replyTemplate":"<replyTemplate>","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/update-inbound-rule":{"post":{"operationId":"dm.update_inbound_rule","summary":"Edit a keyword auto-reply","description":"Replace a keyword rule's keyword, reply or active state. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"publish","x-xholic-mcp-tool":"dm_update_inbound_rule","x-xholic-cli":"xholic dm update-inbound-rule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/update-inbound-rule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm update-inbound-rule --id '<id>' --keyword '<keyword>' --reply-template '<replyTemplate>' --dry-run --idempotency-key 'my-unique-key-1'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_update_inbound_rule\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"keyword\": \"<keyword>\",\n    \"replyTemplate\": \"<replyTemplate>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/update-inbound-rule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"keyword\": \"<keyword>\",\n    \"replyTemplate\": \"<replyTemplate>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/update-inbound-rule\",\n  {\n    \"id\": \"<id>\",\n    \"keyword\": \"<keyword>\",\n    \"replyTemplate\": \"<replyTemplate>\",\n    \"dryRun\": true,\n    \"idempotencyKey\": \"my-unique-key-1\"\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/update-inbound-rule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"keyword\": \"<keyword>\",\n        \"replyTemplate\": \"<replyTemplate>\",\n        \"dryRun\": True,\n        \"idempotencyKey\": \"my-unique-key-1\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/update-inbound-rule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/update-inbound-rule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/update-inbound-rule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"keyword\":\"<keyword>\",\"replyTemplate\":\"<replyTemplate>\",\"dryRun\":true,\"idempotencyKey\":\"my-unique-key-1\"}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Rule id from dm.inbound_rules."},"keyword":{"type":"string","minLength":1,"maxLength":40,"description":"A single word, like GUIDE."},"replyTemplate":{"type":"string","minLength":1,"maxLength":5000,"description":"The message. Variables: [first], [name], [handle], [location], [followers], list fields such as [first_line], with optional fallbacks like [first|there]; spintax like {Hi|Hey}. Write it yourself in the user's voice."},"active":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id","keyword","replyTemplate"]},"example":{"id":"<id>","keyword":"<keyword>","replyTemplate":"<replyTemplate>","dryRun":true,"idempotencyKey":"my-unique-key-1"}}}}}},"/dm/delete-inbound-rule":{"post":{"operationId":"dm.delete_inbound_rule","summary":"Delete a keyword auto-reply","description":"Delete a keyword rule. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["dm"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"dm_delete_inbound_rule","x-xholic-cli":"xholic dm delete-inbound-rule","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/dm/delete-inbound-rule \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"id\":\"<id>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic dm delete-inbound-rule --id '<id>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"dm_delete_inbound_rule\",\n  \"arguments\": {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/dm/delete-inbound-rule\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/dm/delete-inbound-rule\",\n  {\n    \"id\": \"<id>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/dm/delete-inbound-rule\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"id\": \"<id>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"id\":\"<id>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/dm/delete-inbound-rule\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/dm/delete-inbound-rule\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"id\":\"<id>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/dm/delete-inbound-rule\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"id\":\"<id>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Rule id from dm.inbound_rules."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["id"]},"example":{"id":"<id>","dryRun":true}}}}}},"/home/feed":{"get":{"operationId":"home.feed","summary":"Home: for you today","description":"The account's Home: overview numbers, the welcome drafts after sign-up, and up to five ranked cards for today (mentions to answer, leads, queue gaps, posts taking off, trends). Use its workspaceUserId with the home card tools.","tags":["home"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"home_feed","x-xholic-cli":"xholic home feed","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/home/feed' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic home feed"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"home_feed\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/home/feed\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/home/feed\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/home/feed\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/home/feed\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/home/feed\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/home/feed\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/home/card-action":{"post":{"operationId":"home.card_action","summary":"Done, dismiss or snooze a Home card","description":"Mark a Home card done, dismiss it, snooze it or restore it, by the key and type home.feed returned. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["home"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"home_card_action","x-xholic-cli":"xholic home card-action","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/home/card-action \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"workspaceId\":\"<workspaceId>\",\"key\":\"<key>\",\"type\":\"mention\",\"action\":\"done\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic home card-action --workspace-id '<workspaceId>' --key '<key>' --type 'mention' --action 'done' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"home_card_action\",\n  \"arguments\": {\n    \"workspaceId\": \"<workspaceId>\",\n    \"key\": \"<key>\",\n    \"type\": \"mention\",\n    \"action\": \"done\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/home/card-action\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"workspaceId\": \"<workspaceId>\",\n    \"key\": \"<key>\",\n    \"type\": \"mention\",\n    \"action\": \"done\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/home/card-action\",\n  {\n    \"workspaceId\": \"<workspaceId>\",\n    \"key\": \"<key>\",\n    \"type\": \"mention\",\n    \"action\": \"done\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/home/card-action\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"workspaceId\": \"<workspaceId>\",\n        \"key\": \"<key>\",\n        \"type\": \"mention\",\n        \"action\": \"done\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"workspaceId\":\"<workspaceId>\",\"key\":\"<key>\",\"type\":\"mention\",\"action\":\"done\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/home/card-action\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/home/card-action\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"workspaceId\":\"<workspaceId>\",\"key\":\"<key>\",\"type\":\"mention\",\"action\":\"done\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/home/card-action\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"workspaceId\":\"<workspaceId>\",\"key\":\"<key>\",\"type\":\"mention\",\"action\":\"done\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1,"maxLength":160,"description":"workspaceUserId from home.feed, so a stale call never acts on another account."},"key":{"type":"string","minLength":3,"maxLength":160,"description":"The card's key from home.feed."},"type":{"type":"string","enum":["mention","post_reply","close_account_post","contact_repost","breaking_post","recycle_post","post_alert","queue_gap","draft","signal_lead","new_follower","niche_trend","reply_goal","saved_post","market_brief","growth_step","giveaway_ready","learned_check","coming_up"]},"action":{"type":"string","enum":["done","dismiss","snooze","restore"]},"tweetIds":{"description":"For conversation cards: the post ids the card shows.","maxItems":3,"type":"array","items":{"type":"string","pattern":"^\\d{1,32}$"}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["workspaceId","key","type","action"]},"example":{"workspaceId":"<workspaceId>","key":"<key>","type":"mention","action":"done","dryRun":true}}}}}},"/home/welcome-action":{"post":{"operationId":"home.welcome_action","summary":"Welcome drafts","description":"Act on the welcome drafts shown after sign-up: dismiss-message hides the intro, dismiss-draft or restore-draft one draft by position, retry rebuilds drafts that failed. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["home"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"home_welcome_action","x-xholic-cli":"xholic home welcome-action","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/home/welcome-action \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"workspaceId\":\"<workspaceId>\",\"action\":\"dismiss-message\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic home welcome-action --workspace-id '<workspaceId>' --action 'dismiss-message' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"home_welcome_action\",\n  \"arguments\": {\n    \"workspaceId\": \"<workspaceId>\",\n    \"action\": \"dismiss-message\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/home/welcome-action\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"workspaceId\": \"<workspaceId>\",\n    \"action\": \"dismiss-message\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/home/welcome-action\",\n  {\n    \"workspaceId\": \"<workspaceId>\",\n    \"action\": \"dismiss-message\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/home/welcome-action\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"workspaceId\": \"<workspaceId>\",\n        \"action\": \"dismiss-message\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"workspaceId\":\"<workspaceId>\",\"action\":\"dismiss-message\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/home/welcome-action\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/home/welcome-action\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"workspaceId\":\"<workspaceId>\",\"action\":\"dismiss-message\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/home/welcome-action\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"workspaceId\":\"<workspaceId>\",\"action\":\"dismiss-message\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1,"maxLength":160,"description":"workspaceUserId from home.feed, so a stale call never acts on another account."},"action":{"type":"string","enum":["dismiss-message","dismiss-draft","restore-draft","retry"]},"position":{"description":"Required for dismiss-draft and restore-draft: the draft's position.","type":"integer","minimum":0,"maximum":2},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["workspaceId","action"]},"example":{"workspaceId":"<workspaceId>","action":"dismiss-message","dryRun":true}}}}}},"/settings/account":{"get":{"operationId":"settings.account","summary":"Xholic account","description":"The signed-in Xholic user's account: name, email, avatar and whether their main X login is still connected.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_account","x-xholic-cli":"xholic settings account","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/account' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings account"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_account\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/account\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/account\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/account\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/account\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/account\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/account\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/reply-preferences":{"get":{"operationId":"settings.reply_preferences","summary":"Reply rules","description":"The account's custom rules for reply drafts (what every Xholic reply writer must follow).","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_reply_preferences","x-xholic-cli":"xholic settings reply-preferences","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/reply-preferences' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings reply-preferences"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_reply_preferences\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/reply-preferences\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/reply-preferences\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/reply-preferences\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/reply-preferences\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/reply-preferences\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/reply-preferences\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/update-reply-preferences":{"post":{"operationId":"settings.update_reply_preferences","summary":"Update reply rules","description":"Replace the account's custom reply rules. Read settings.reply_preferences first; null or leaving it out clears the rules. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_update_reply_preferences","x-xholic-cli":"xholic settings update-reply-preferences","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/update-reply-preferences \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings update-reply-preferences --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_update_reply_preferences\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/update-reply-preferences\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/update-reply-preferences\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/update-reply-preferences\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/update-reply-preferences\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/update-reply-preferences\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/update-reply-preferences\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"customRules":{"nullable":true,"type":"string","maxLength":500},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/settings/about-you":{"get":{"operationId":"settings.about_you","summary":"About You settings","description":"The account's About You settings as Stark shows them: the free-text description, selected topics and tones. To change them use update_account_context.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_about_you","x-xholic-cli":"xholic settings about-you","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/about-you' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings about-you"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_about_you\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/about-you\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/about-you\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/about-you\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/about-you\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/about-you\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/about-you\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/set-account-type":{"post":{"operationId":"settings.set_account_type","summary":"Set account type","description":"Tell Xholic whether the account is a person, a brand or a topic page, which changes the voice every writer uses. Pass null to go back to the detected type. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_set_account_type","x-xholic-cli":"xholic settings set-account-type","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/set-account-type \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"override\":\"PERSON\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings set-account-type --override 'PERSON' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_set_account_type\",\n  \"arguments\": {\n    \"override\": \"PERSON\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/set-account-type\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"override\": \"PERSON\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/set-account-type\",\n  {\n    \"override\": \"PERSON\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/set-account-type\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"override\": \"PERSON\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"override\":\"PERSON\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/set-account-type\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/set-account-type\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"override\":\"PERSON\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/set-account-type\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"override\":\"PERSON\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"override":{"nullable":true,"type":"string","enum":["PERSON","BRAND","TOPIC"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["override"]},"example":{"override":"PERSON","dryRun":true}}}}}},"/settings/suggest-interests":{"post":{"operationId":"settings.suggest_interests","summary":"Suggest topics","description":"Suggest About You topics from the account's recent posts. Free, a few per day; it changes nothing until the user saves them.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_suggest_interests","x-xholic-cli":"xholic settings suggest-interests","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/suggest-interests \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings suggest-interests --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_suggest_interests\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/suggest-interests\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/suggest-interests\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/suggest-interests\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/suggest-interests\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/suggest-interests\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/suggest-interests\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/settings/personalization":{"get":{"operationId":"settings.personalization","summary":"Personalization settings","description":"The account's audience override, style vocabulary override and global rules that every writer reads, plus the generated style guide.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_personalization","x-xholic-cli":"xholic settings personalization","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/personalization' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings personalization"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_personalization\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/personalization\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/personalization\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/personalization\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/personalization\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/personalization\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/personalization\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/update-personalization":{"post":{"operationId":"settings.update_personalization","summary":"Update personalization","description":"Replace the audience override, style vocabulary override and global rules. Read settings.personalization first and send all three: any field left out is cleared. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_update_personalization","x-xholic-cli":"xholic settings update-personalization","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/update-personalization \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings update-personalization --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_update_personalization\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/update-personalization\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/update-personalization\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/update-personalization\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/update-personalization\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/update-personalization\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/update-personalization\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"audienceOverride":{"nullable":true,"type":"string","maxLength":600},"styleVocabularyOverride":{"nullable":true,"type":"string","maxLength":1000},"globalRules":{"nullable":true,"type":"string","maxLength":500},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/settings/regenerate-style-guide":{"post":{"operationId":"settings.regenerate_style_guide","summary":"Rebuild the style guide","description":"Rebuild the account's writing style guide from its posts and style creators. Free, capped per day; it replaces the current guide. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_regenerate_style_guide","x-xholic-cli":"xholic settings regenerate-style-guide","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/regenerate-style-guide \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings regenerate-style-guide --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_regenerate_style_guide\",\n  \"arguments\": {\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/regenerate-style-guide\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/regenerate-style-guide\",\n  {\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/regenerate-style-guide\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/regenerate-style-guide\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/regenerate-style-guide\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/regenerate-style-guide\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}}},"example":{"dryRun":true}}}}}},"/settings/style-creators":{"get":{"operationId":"settings.style_creators","summary":"Style creators","description":"The up to 3 creators the account writes like (favourite creators), with the current count.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_style_creators","x-xholic-cli":"xholic settings style-creators","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/style-creators' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings style-creators"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_style_creators\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/style-creators\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/style-creators\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/style-creators\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/style-creators\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/style-creators\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/style-creators\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/search-style-creators":{"get":{"operationId":"settings.search_style_creators","summary":"Find style creators","description":"Search X creators to write like, by name or handle (at least 2 characters). Returns creator ids for settings.add_style_creator.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_search_style_creators","x-xholic-cli":"xholic settings search-style-creators","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/search-style-creators?q=%3Cq%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings search-style-creators --q '<q>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_search_style_creators\",\n  \"arguments\": {\n    \"q\": \"<q>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/search-style-creators?q=%3Cq%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/search-style-creators\", {\n  params: {\n    \"q\": \"<q>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/search-style-creators\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"q\": \"<q>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/search-style-creators?q=%3Cq%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/search-style-creators?q=%3Cq%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/search-style-creators?q=%3Cq%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":100},"example":"<q>"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/add-style-creator":{"post":{"operationId":"settings.add_style_creator","summary":"Add a style creator","description":"Add one creator to write like (up to 3). Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_add_style_creator","x-xholic-cli":"xholic settings add-style-creator","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/add-style-creator \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings add-style-creator --creator-id '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_add_style_creator\",\n  \"arguments\": {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/add-style-creator\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/add-style-creator\",\n  {\n    \"creatorId\": \"<creatorId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/add-style-creator\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorId\": \"<creatorId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorId\":\"<creatorId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/add-style-creator\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/add-style-creator\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/add-style-creator\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorId\":\"<creatorId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorId":{"type":"string","minLength":1,"maxLength":120,"description":"Creator id from settings.search_style_creators."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorId"]},"example":{"creatorId":"<creatorId>","dryRun":true}}}}}},"/settings/save-style-creators":{"post":{"operationId":"settings.save_style_creators","summary":"Set style creators","description":"Replace the creators to write like with this list (up to 3). Leaving one out removes it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"settings_save_style_creators","x-xholic-cli":"xholic settings save-style-creators","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/settings/save-style-creators \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"creatorIds\":[\"<creatorId>\"],\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic settings save-style-creators --creator-ids '<creatorId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_save_style_creators\",\n  \"arguments\": {\n    \"creatorIds\": [\n      \"<creatorId>\"\n    ],\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/save-style-creators\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"creatorIds\": [\n      \"<creatorId>\"\n    ],\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/settings/save-style-creators\",\n  {\n    \"creatorIds\": [\n      \"<creatorId>\"\n    ],\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/settings/save-style-creators\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"creatorIds\": [\n            \"<creatorId>\"\n        ],\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"creatorIds\":[\"<creatorId>\"],\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/settings/save-style-creators\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/save-style-creators\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"creatorIds\":[\"<creatorId>\"],\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/save-style-creators\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"creatorIds\":[\"<creatorId>\"],\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"creatorIds":{"maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"description":"Creator id from settings.search_style_creators."}},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["creatorIds"]},"example":{"creatorIds":["<creatorId>"],"dryRun":true}}}}}},"/settings/usage":{"get":{"operationId":"settings.usage","summary":"X data usage","description":"The user's external X data usage per feature over the last few days (default 30).","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_usage","x-xholic-cli":"xholic settings usage","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/usage' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings usage"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_usage\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/usage\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/usage\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/usage\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/usage\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/usage\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/usage\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":90}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/settings/quota":{"get":{"operationId":"settings.quota","summary":"Daily limits","description":"What the plan allows today per feature (posts, remixes, scheduling, agents) and how much is used, plus the AI credit counters. Check it before a batch so a limit doesn't stop it halfway. For just the AI credit balance, use credits.balance.","tags":["settings"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"settings_quota","x-xholic-cli":"xholic settings quota","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/settings/quota' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic settings quota"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"settings_quota\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/settings/quota\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/settings/quota\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/settings/quota\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/settings/quota\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/settings/quota\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/settings/quota\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"details","in":"query","required":false,"schema":{"description":"Include the per-feature breakdown.","type":"boolean"},"description":"Include the per-feature breakdown."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/context/products":{"get":{"operationId":"context.products","summary":"Products and context","description":"The account's saved products with their facts (what it is, audience, features, proof), analysis limits and removal notices. Writers and Signals read these facts.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"context_products","x-xholic-cli":"xholic context products","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/context/products' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic context products"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_products\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/products\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/context/products\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/context/products\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/context/products\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/products\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/products\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/context/bio-product-suggestion":{"get":{"operationId":"context.bio_product_suggestion","summary":"Product from the bio link","description":"The link in the account's X bio when it isn't a saved product yet, so it can be added with context.add_product.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"context_bio_product_suggestion","x-xholic-cli":"xholic context bio-product-suggestion","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/context/bio-product-suggestion' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic context bio-product-suggestion"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_bio_product_suggestion\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/bio-product-suggestion\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/context/bio-product-suggestion\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/context/bio-product-suggestion\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/context/bio-product-suggestion\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/bio-product-suggestion\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/bio-product-suggestion\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/context/add-product":{"post":{"operationId":"context.add_product","summary":"Add a product","description":"Add a product by its website URL. Xholic reads the site and saves its facts; this counts against the plan's daily product analyses. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"context_add_product","x-xholic-cli":"xholic context add-product","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/add-product \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context add-product --url 'https://example.com/hooks/xholic' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_add_product\",\n  \"arguments\": {\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/add-product\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/add-product\",\n  {\n    \"url\": \"https://example.com/hooks/xholic\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/add-product\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"url\": \"https://example.com/hooks/xholic\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/add-product\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/add-product\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/add-product\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"url\":\"https://example.com/hooks/xholic\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"The product's website."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["url"]},"example":{"url":"https://example.com/hooks/xholic","dryRun":true}}}}}},"/context/refresh-product":{"post":{"operationId":"context.refresh_product","summary":"Refresh a product","description":"Read the product's website again and update its facts. Counts against the plan's daily product analyses. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"context_refresh_product","x-xholic-cli":"xholic context refresh-product","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/refresh-product \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context refresh-product --product-id '<productId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_refresh_product\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/refresh-product\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/refresh-product\",\n  {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/refresh-product\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/refresh-product\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/refresh-product\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/refresh-product\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":1,"maxLength":120,"description":"Product id from context.products."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId"]},"example":{"productId":"<productId>","dryRun":true}}}}}},"/context/set-product-auto-refresh":{"post":{"operationId":"context.set_product_auto_refresh","summary":"Product auto-refresh","description":"Choose whether a product keeps refreshing automatically after its facts were edited by hand. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"context_set_product_auto_refresh","x-xholic-cli":"xholic context set-product-auto-refresh","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/set-product-auto-refresh \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"whenEdited\":false,\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context set-product-auto-refresh --product-id '<productId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_set_product_auto_refresh\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"whenEdited\": false,\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/set-product-auto-refresh\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"whenEdited\": false,\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/set-product-auto-refresh\",\n  {\n    \"productId\": \"<productId>\",\n    \"whenEdited\": false,\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/set-product-auto-refresh\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"whenEdited\": False,\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"whenEdited\":false,\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/set-product-auto-refresh\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/set-product-auto-refresh\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"whenEdited\":false,\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/set-product-auto-refresh\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"whenEdited\":false,\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":1,"maxLength":120,"description":"Product id from context.products."},"whenEdited":{"type":"boolean"},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId","whenEdited"]},"example":{"productId":"<productId>","whenEdited":false,"dryRun":true}}}}}},"/context/update-product":{"post":{"operationId":"context.update_product","summary":"Edit product facts","description":"Replace a product's facts. Read them with context.products, change what the user asked, and send the whole structuredFacts object back: lists left out are cleared. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"context_update_product","x-xholic-cli":"xholic context update-product","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/update-product \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"structuredFacts\":{},\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context update-product --product-id '<productId>' --structured-facts '{}' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_update_product\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"structuredFacts\": {},\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/update-product\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"structuredFacts\": {},\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/update-product\",\n  {\n    \"productId\": \"<productId>\",\n    \"structuredFacts\": {},\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/update-product\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"structuredFacts\": {},\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"structuredFacts\":{},\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/update-product\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/update-product\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"structuredFacts\":{},\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/update-product\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"structuredFacts\":{},\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":1,"maxLength":120,"description":"Product id from context.products."},"structuredFacts":{"type":"object","properties":{},"additionalProperties":{},"description":"The product's full facts object (name, tagline, summary, audience, features, benefits, proofPoints...) as context.products returns it."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId","structuredFacts"]},"example":{"productId":"<productId>","structuredFacts":{},"dryRun":true}}}}}},"/context/delete-product":{"post":{"operationId":"context.delete_product","summary":"Remove a product","description":"Remove a product from the account's context. Writers and Signals stop using it. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"context_delete_product","x-xholic-cli":"xholic context delete-product","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/delete-product \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context delete-product --product-id '<productId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_delete_product\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/delete-product\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/delete-product\",\n  {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/delete-product\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/delete-product\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/delete-product\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/delete-product\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":1,"maxLength":120,"description":"Product id from context.products."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId"]},"example":{"productId":"<productId>","dryRun":true}}}}}},"/context/dismiss-product-notice":{"post":{"operationId":"context.dismiss_product_notice","summary":"Dismiss a removal notice","description":"Hide the notice that a product was removed automatically.","tags":["context"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"context_dismiss_product_notice","x-xholic-cli":"xholic context dismiss-product-notice","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/context/dismiss-product-notice \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"productId\":\"<productId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic context dismiss-product-notice --product-id '<productId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"context_dismiss_product_notice\",\n  \"arguments\": {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/context/dismiss-product-notice\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/context/dismiss-product-notice\",\n  {\n    \"productId\": \"<productId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/context/dismiss-product-notice\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"productId\": \"<productId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"productId\":\"<productId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/context/dismiss-product-notice\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/context/dismiss-product-notice\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"productId\":\"<productId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/context/dismiss-product-notice\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"productId\":\"<productId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string","minLength":1,"maxLength":120,"description":"Product id from context.products."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["productId"]},"example":{"productId":"<productId>","dryRun":true}}}}}},"/ask/conversations":{"get":{"operationId":"ask.conversations","summary":"Ask conversations","description":"The user's past Ask conversations, newest first, with search and paging.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"ask_conversations","x-xholic-cli":"xholic ask conversations","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/ask/conversations' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic ask conversations"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_conversations\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/conversations\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/ask/conversations\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/ask/conversations\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/ask/conversations\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/conversations\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/conversations\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","maxLength":120}},{"name":"cursor","in":"query","required":false,"schema":{"description":"Cursor from the previous page.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Cursor from the previous page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["ACTIVE","ARCHIVED"]}},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/ask/conversation":{"get":{"operationId":"ask.conversation","summary":"Ask conversation","description":"One Ask conversation with its messages and drafts.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"ask_conversation","x-xholic-cli":"xholic ask conversation","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/ask/conversation?id=%3Cid%3E' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic ask conversation --id '<id>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_conversation\",\n  \"arguments\": {\n    \"id\": \"<id>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/conversation?id=%3Cid%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/ask/conversation\", {\n  params: {\n    \"id\": \"<id>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/ask/conversation\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"id\": \"<id>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/ask/conversation?id=%3Cid%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/conversation?id=%3Cid%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/conversation?id=%3Cid%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Conversation id from ask.conversations."},"example":"<id>","description":"Conversation id from ask.conversations."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/ask/catalog":{"get":{"operationId":"ask.catalog","summary":"Ask models and skills","description":"Ask's models the plan can use, its built-in skills (playbooks) and the user's custom skills.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"ask_catalog","x-xholic-cli":"xholic ask catalog","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/ask/catalog' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic ask catalog"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_catalog\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/catalog\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/ask/catalog\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/ask/catalog\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/ask/catalog\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/catalog\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/catalog\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/memory/list":{"get":{"operationId":"memory.list","summary":"Saved memories","description":"Everything the user told Xholic to remember. Add with remember, remove with forget.","tags":["memory"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"memory_list","x-xholic-cli":"xholic memory list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/memory/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic memory list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"memory_list\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/memory/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/memory/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/memory/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/memory/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/memory/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/memory/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/ask/create-skill":{"post":{"operationId":"ask.create_skill","summary":"Create an Ask skill","description":"Save a reusable Ask skill: a named prompt the user can run again. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"ask_create_skill","x-xholic-cli":"xholic ask create-skill","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/ask/create-skill \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic ask create-skill --title '<title>' --prompt '<prompt>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_create_skill\",\n  \"arguments\": {\n    \"title\": \"<title>\",\n    \"prompt\": \"<prompt>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/create-skill\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"title\": \"<title>\",\n    \"prompt\": \"<prompt>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/ask/create-skill\",\n  {\n    \"title\": \"<title>\",\n    \"prompt\": \"<prompt>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/ask/create-skill\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"title\": \"<title>\",\n        \"prompt\": \"<prompt>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/ask/create-skill\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/create-skill\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/create-skill\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"description":{"nullable":true,"type":"string","maxLength":200},"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"What Ask should do when the skill runs, in the user's words."},"model":{"description":"Ask model the skill runs on; leave out for the user's default.","nullable":true,"type":"string","enum":["luna","sol","sonnet","opus","astra","fable"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["title","prompt"]},"example":{"title":"<title>","prompt":"<prompt>","dryRun":true}}}}}},"/ask/update-skill":{"post":{"operationId":"ask.update_skill","summary":"Edit an Ask skill","description":"Replace a custom Ask skill's title, description, prompt and model. Send every field: this is a full replace. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"ask_update_skill","x-xholic-cli":"xholic ask update-skill","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/ask/update-skill \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"skillId\":\"<skillId>\",\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic ask update-skill --skill-id '<skillId>' --title '<title>' --prompt '<prompt>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_update_skill\",\n  \"arguments\": {\n    \"skillId\": \"<skillId>\",\n    \"title\": \"<title>\",\n    \"prompt\": \"<prompt>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/update-skill\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"skillId\": \"<skillId>\",\n    \"title\": \"<title>\",\n    \"prompt\": \"<prompt>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/ask/update-skill\",\n  {\n    \"skillId\": \"<skillId>\",\n    \"title\": \"<title>\",\n    \"prompt\": \"<prompt>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/ask/update-skill\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"skillId\": \"<skillId>\",\n        \"title\": \"<title>\",\n        \"prompt\": \"<prompt>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"skillId\":\"<skillId>\",\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/ask/update-skill\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/update-skill\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"skillId\":\"<skillId>\",\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/update-skill\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"skillId\":\"<skillId>\",\"title\":\"<title>\",\"prompt\":\"<prompt>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Custom skill id from ask.catalog."},"title":{"type":"string","minLength":1,"maxLength":80},"description":{"nullable":true,"type":"string","maxLength":200},"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"What Ask should do when the skill runs, in the user's words."},"model":{"description":"Ask model the skill runs on; leave out for the user's default.","nullable":true,"type":"string","enum":["luna","sol","sonnet","opus","astra","fable"]},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["skillId","title","prompt"]},"example":{"skillId":"<skillId>","title":"<title>","prompt":"<prompt>","dryRun":true}}}}}},"/ask/delete-skill":{"post":{"operationId":"ask.delete_skill","summary":"Delete an Ask skill","description":"Delete a custom Ask skill. Call it only when the user asked for this in the conversation; never on your own initiative.","tags":["ask"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"write","x-xholic-mcp-tool":"ask_delete_skill","x-xholic-cli":"xholic ask delete-skill","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl -X POST https://api.xholic.ai/v1/ask/delete-skill \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"skillId\":\"<skillId>\",\"dryRun\":true}'"},{"lang":"shell","label":"Xholic CLI","source":"xholic ask delete-skill --skill-id '<skillId>' --dry-run"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"ask_delete_skill\",\n  \"arguments\": {\n    \"skillId\": \"<skillId>\",\n    \"dryRun\": true\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/ask/delete-skill\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.XHOLIC_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"skillId\": \"<skillId>\",\n    \"dryRun\": true\n  }),\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.post(\n  \"https://api.xholic.ai/v1/ask/delete-skill\",\n  {\n    \"skillId\": \"<skillId>\",\n    \"dryRun\": true\n  },\n  { headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` } },\n);\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.post(\n    \"https://api.xholic.ai/v1/ask/delete-skill\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    json={\n        \"skillId\": \"<skillId>\",\n        \"dryRun\": True\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := strings.NewReader(`{\"skillId\":\"<skillId>\",\"dryRun\":true}`)\n\treq, _ := http.NewRequest(\"POST\", \"https://api.xholic.ai/v1/ask/delete-skill\", body)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tout, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(out))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/ask/delete-skill\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('XHOLIC_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => '{\"skillId\":\"<skillId>\",\"dryRun\":true}',\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/ask/delete-skill\")\nreq = Net::HTTP::Post.new(uri, \"Content-Type\" => \"application/json\")\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nreq.body = '{\"skillId\":\"<skillId>\",\"dryRun\":true}'\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Custom skill id from ask.catalog."},"account":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"dryRun":{"description":"Return exactly what would happen without doing it.","type":"boolean"},"idempotencyKey":{"description":"A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.","type":"string","minLength":8,"maxLength":200}},"required":["skillId"]},"example":{"skillId":"<skillId>","dryRun":true}}}}}},"/billing/status":{"get":{"operationId":"billing.status","summary":"Plan and subscription","description":"The user's plan and subscription state, including trial dates. Read-only: plan changes, cancelling and payments happen in the Xholic app.","tags":["billing"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"billing_status","x-xholic-cli":"xholic billing status","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/billing/status' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic billing status"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"billing_status\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/billing/status\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/billing/status\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/billing/status\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/billing/status\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/billing/status\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/billing/status\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/billing/details":{"get":{"operationId":"billing.details","summary":"Billing details","description":"The billing details on file for the subscription. Read-only: changes happen in the Xholic app.","tags":["billing"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"billing_details","x-xholic-cli":"xholic billing details","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/billing/details' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic billing details"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"billing_details\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/billing/details\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/billing/details\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/billing/details\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/billing/details\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/billing/details\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/billing/details\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/billing/payments":{"get":{"operationId":"billing.payments","summary":"Payment history","description":"Past payments and invoices. Read-only.","tags":["billing"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"billing_payments","x-xholic-cli":"xholic billing payments","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/billing/payments' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic billing payments"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"billing_payments\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/billing/payments\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/billing/payments\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/billing/payments\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/billing/payments\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/billing/payments\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/billing/payments\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/billing/credit-packs":{"get":{"operationId":"billing.credit_packs","summary":"AI credit packs","description":"The AI credit packs the user can buy and their prices. Buying happens in the Xholic app; point the user there.","tags":["billing"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"billing_credit_packs","x-xholic-cli":"xholic billing credit-packs","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/billing/credit-packs' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic billing credit-packs"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"billing_credit_packs\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/billing/credit-packs\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/billing/credit-packs\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/billing/credit-packs\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/billing/credit-packs\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/billing/credit-packs\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/billing/credit-packs\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/billing/trial-eligibility":{"get":{"operationId":"billing.trial_eligibility","summary":"Trial eligibility","description":"Whether a checkout would still include the free trial for this user.","tags":["billing"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"billing_trial_eligibility","x-xholic-cli":"xholic billing trial-eligibility","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/billing/trial-eligibility' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic billing trial-eligibility"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"billing_trial_eligibility\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/billing/trial-eligibility\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/billing/trial-eligibility\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/billing/trial-eligibility\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/billing/trial-eligibility\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/billing/trial-eligibility\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/billing/trial-eligibility\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/sharing/list":{"get":{"operationId":"sharing.list","summary":"Account sharing","description":"Who the user shared their X accounts with and which accounts others shared with them, with roles and pending invites. Read-only: inviting, accepting and changing roles happen in the Xholic app.","tags":["sharing"],"security":[{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"sharing_list","x-xholic-cli":"xholic sharing list","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/sharing/list' \\\n  -H \"Authorization: Bearer $XHOLIC_API_KEY\""},{"lang":"shell","label":"Xholic CLI","source":"xholic sharing list"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"sharing_list\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/sharing/list\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/sharing/list\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/sharing/list\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/sharing/list\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/sharing/list\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/sharing/list\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/profile-report":{"get":{"operationId":"free_tools.profile_report","summary":"X profile report","description":"A free report on any public X account. report: analytics (followers, posting and engagement over recent posts), audit (profile and content checklist with fixes), best-time (when its posts do best; pass timezone), engagement-rate (average engagement rate with a benchmark), media (its profile picture and header image at full size).","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_profile_report","x-xholic-cli":"xholic free-tools profile-report","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/profile-report?handle=%40founder&report=analytics'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools profile-report --handle '@founder' --report 'analytics'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_profile_report\",\n  \"arguments\": {\n    \"handle\": \"@founder\",\n    \"report\": \"analytics\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/profile-report?handle=%40founder&report=analytics\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/profile-report\", {\n  params: {\n    \"handle\": \"@founder\",\n    \"report\": \"analytics\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/profile-report\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"handle\": \"@founder\",\n        \"report\": \"analytics\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/profile-report?handle=%40founder&report=analytics\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/profile-report?handle=%40founder&report=analytics\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/profile-report?handle=%40founder&report=analytics\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"X username, with or without @."},"example":"@founder","description":"X username, with or without @."},{"name":"report","in":"query","required":true,"schema":{"type":"string","enum":["analytics","audit","best-time","engagement-rate","media"]},"example":"analytics"},{"name":"timezone","in":"query","required":false,"schema":{"description":"For analytics and best-time: IANA timezone for times of day.","type":"string","minLength":1,"maxLength":80},"description":"For analytics and best-time: IANA timezone for times of day."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/shadowban-check":{"get":{"operationId":"free_tools.shadowban_check","summary":"Shadowban check","description":"Check whether a public X account looks shadowbanned or limited in search, replies and suggestions. A few fresh checks per day; recently checked handles come back from storage.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"shadowban_check","x-xholic-cli":"xholic free-tools shadowban-check","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/shadowban-check?handle=%40founder'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools shadowban-check --handle '@founder'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"shadowban_check\",\n  \"arguments\": {\n    \"handle\": \"@founder\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/shadowban-check?handle=%40founder\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/shadowban-check\", {\n  params: {\n    \"handle\": \"@founder\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/shadowban-check\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"handle\": \"@founder\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/shadowban-check?handle=%40founder\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/shadowban-check?handle=%40founder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/shadowban-check?handle=%40founder\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"X username, with or without @."},"example":"@founder","description":"X username, with or without @."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/trend-regions":{"get":{"operationId":"free_tools.trend_regions","summary":"X trend regions","description":"The regions X trends are available for, with their region slugs for x_trends.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_trend_regions","x-xholic-cli":"xholic free-tools trend-regions","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/trend-regions'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools trend-regions"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_trend_regions\",\n  \"arguments\": {}\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/trend-regions\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/trend-regions\", {\n  params: {},\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/trend-regions\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={},\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/trend-regions\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/trend-regions\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/trend-regions\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/trends":{"get":{"operationId":"free_tools.trends","summary":"X trends","description":"What is trending on X in a region right now (from Xholic's recent snapshot). Use worldwide or a slug from x_trend_regions such as united-states.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_trends","x-xholic-cli":"xholic free-tools trends","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/trends?region=%3Cregion%3E'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools trends --region '<region>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_trends\",\n  \"arguments\": {\n    \"region\": \"<region>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/trends?region=%3Cregion%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/trends\", {\n  params: {\n    \"region\": \"<region>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/trends\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"region\": \"<region>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/trends?region=%3Cregion%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/trends?region=%3Cregion%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/trends?region=%3Cregion%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"region","in":"query","required":true,"schema":{"type":"string","pattern":"^[a-z-]{1,64}$","description":"Region slug such as worldwide or united-states."},"example":"<region>","description":"Region slug such as worldwide or united-states."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/read-thread":{"get":{"operationId":"free_tools.read_thread","summary":"Read a thread","description":"Unroll an X thread from the link to any of its posts into one readable piece, with its media.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"read_thread","x-xholic-cli":"xholic free-tools read-thread","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/read-thread?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools read-thread --url 'https://example.com/hooks/xholic'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"read_thread\",\n  \"arguments\": {\n    \"url\": \"https://example.com/hooks/xholic\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/read-thread?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/read-thread\", {\n  params: {\n    \"url\": \"https://example.com/hooks/xholic\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/read-thread\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"url\": \"https://example.com/hooks/xholic\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/read-thread?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/read-thread?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/read-thread?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":500,"description":"Link to a post in the thread."},"example":"https://example.com/hooks/xholic","description":"Link to a post in the thread."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/card-preview":{"get":{"operationId":"free_tools.card_preview","summary":"Link card preview","description":"Show how a link will look as a card on X (title, description, image, card type) and what is missing from its tags.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"card_preview","x-xholic-cli":"xholic free-tools card-preview","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/card-preview?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools card-preview --url 'https://example.com/hooks/xholic'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"card_preview\",\n  \"arguments\": {\n    \"url\": \"https://example.com/hooks/xholic\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/card-preview?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/card-preview\", {\n  params: {\n    \"url\": \"https://example.com/hooks/xholic\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/card-preview\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"url\": \"https://example.com/hooks/xholic\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/card-preview?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/card-preview?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/card-preview?url=https%3A%2F%2Fexample.com%2Fhooks%2Fxholic\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":2048,"description":"The page link to check."},"example":"https://example.com/hooks/xholic","description":"The page link to check."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/post-media":{"get":{"operationId":"free_tools.post_media","summary":"Post media links","description":"Get download links for the video, GIF or images in a public X post.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_post_media","x-xholic-cli":"xholic free-tools post-media","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/post-media?tweetUrl=%3CtweetUrl%3E&type=video'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools post-media --tweet-url '<tweetUrl>' --type 'video'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_post_media\",\n  \"arguments\": {\n    \"tweetUrl\": \"<tweetUrl>\",\n    \"type\": \"video\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/post-media?tweetUrl=%3CtweetUrl%3E&type=video\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/post-media\", {\n  params: {\n    \"tweetUrl\": \"<tweetUrl>\",\n    \"type\": \"video\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/post-media\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"tweetUrl\": \"<tweetUrl>\",\n        \"type\": \"video\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/post-media?tweetUrl=%3CtweetUrl%3E&type=video\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/post-media?tweetUrl=%3CtweetUrl%3E&type=video\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/post-media?tweetUrl=%3CtweetUrl%3E&type=video\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"tweetUrl","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":500,"description":"Link to the X post."},"example":"<tweetUrl>","description":"Link to the X post."},{"name":"type","in":"query","required":true,"schema":{"type":"string","enum":["video","gif","image"]},"example":"video"},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/username-check":{"get":{"operationId":"free_tools.username_check","summary":"Username check","description":"Whether an X username is available, with similar available suggestions when it is taken.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_username_check","x-xholic-cli":"xholic free-tools username-check","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/username-check?handle=%40founder'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools username-check --handle '@founder'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_username_check\",\n  \"arguments\": {\n    \"handle\": \"@founder\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/username-check?handle=%40founder\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/username-check\", {\n  params: {\n    \"handle\": \"@founder\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/username-check\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"handle\": \"@founder\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/username-check?handle=%40founder\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/username-check?handle=%40founder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/username-check?handle=%40founder\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"X username, with or without @."},"example":"@founder","description":"X username, with or without @."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/x-id-convert":{"get":{"operationId":"free_tools.x_id_convert","summary":"X ID converter","description":"Convert between an X username and its numeric user id, in either direction.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_id_converter","x-xholic-cli":"xholic free-tools x-id-convert","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/x-id-convert?input=%3Cinput%3E'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools x-id-convert --input '<input>'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_id_converter\",\n  \"arguments\": {\n    \"input\": \"<input>\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/x-id-convert?input=%3Cinput%3E\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/x-id-convert\", {\n  params: {\n    \"input\": \"<input>\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/x-id-convert\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"input\": \"<input>\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/x-id-convert?input=%3Cinput%3E\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/x-id-convert?input=%3Cinput%3E\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/x-id-convert?input=%3Cinput%3E\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"input","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"A username, user id or profile link."},"example":"<input>","description":"A username, user id or profile link."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/follower-count":{"get":{"operationId":"free_tools.follower_count","summary":"Follower count","description":"The current follower and following counts of a public X account.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_follower_count","x-xholic-cli":"xholic free-tools follower-count","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/follower-count?handle=%40founder'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools follower-count --handle '@founder'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_follower_count\",\n  \"arguments\": {\n    \"handle\": \"@founder\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/follower-count?handle=%40founder\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/follower-count\", {\n  params: {\n    \"handle\": \"@founder\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/follower-count\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"handle\": \"@founder\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/follower-count?handle=%40founder\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/follower-count?handle=%40founder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/follower-count?handle=%40founder\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"X username, with or without @."},"example":"@founder","description":"X username, with or without @."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/account-worth":{"get":{"operationId":"free_tools.account_worth","summary":"Account worth","description":"An estimate of what a public X account is worth, from its followers, views and engagement on recent posts.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"x_account_worth","x-xholic-cli":"xholic free-tools account-worth","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/account-worth?handle=%40founder'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools account-worth --handle '@founder'"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"x_account_worth\",\n  \"arguments\": {\n    \"handle\": \"@founder\"\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/account-worth?handle=%40founder\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/account-worth\", {\n  params: {\n    \"handle\": \"@founder\"\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/account-worth\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"handle\": \"@founder\"\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/account-worth?handle=%40founder\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/account-worth?handle=%40founder\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/account-worth?handle=%40founder\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"description":"X username, with or without @."},"example":"@founder","description":"X username, with or without @."},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}},"/free-tools/engagement-calculator":{"get":{"operationId":"free_tools.engagement_calculator","summary":"Engagement rate calculator","description":"Calculate engagement rates from numbers you already have (followers, impressions, likes, replies, reposts, quotes). No X lookup.","tags":["free_tools"],"security":[{},{"bearerAuth":[]}],"x-xholic-kind":"read","x-xholic-mcp-tool":"engagement_calculator","x-xholic-cli":"xholic free-tools engagement-calculator","x-codeSamples":[{"lang":"shell","label":"cURL","source":"curl 'https://api.xholic.ai/v1/free-tools/engagement-calculator?followersCount=1&impressions=1&likes=1&replies=1&reposts=1&quotes=1'"},{"lang":"shell","label":"Xholic CLI","source":"xholic free-tools engagement-calculator --followers-count 1 --impressions 1 --likes 1 --replies 1 --reposts 1 --quotes 1"},{"lang":"json","label":"MCP tool call","source":"{\n  \"name\": \"engagement_calculator\",\n  \"arguments\": {\n    \"followersCount\": 1,\n    \"impressions\": 1,\n    \"likes\": 1,\n    \"replies\": 1,\n    \"reposts\": 1,\n    \"quotes\": 1\n  }\n}"},{"lang":"javascript","label":"JavaScript","source":"const response = await fetch(\"https://api.xholic.ai/v1/free-tools/engagement-calculator?followersCount=1&impressions=1&likes=1&replies=1&reposts=1&quotes=1\", {\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconst result = await response.json();\nconsole.log(result.summary);"},{"lang":"javascript","label":"Node.js (axios)","source":"import axios from \"axios\";\n\nconst { data } = await axios.get(\"https://api.xholic.ai/v1/free-tools/engagement-calculator\", {\n  params: {\n    \"followersCount\": 1,\n    \"impressions\": 1,\n    \"likes\": 1,\n    \"replies\": 1,\n    \"reposts\": 1,\n    \"quotes\": 1\n  },\n  headers: { Authorization: `Bearer ${process.env.XHOLIC_API_KEY}` },\n});\nconsole.log(data.summary);"},{"lang":"python","label":"Python","source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://api.xholic.ai/v1/free-tools/engagement-calculator\",\n    headers={\"Authorization\": f\"Bearer {os.environ['XHOLIC_API_KEY']}\"},\n    params={\n        \"followersCount\": 1,\n        \"impressions\": 1,\n        \"likes\": 1,\n        \"replies\": 1,\n        \"reposts\": 1,\n        \"quotes\": 1\n    },\n)\nprint(response.json()[\"summary\"])"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\treq, _ := http.NewRequest(\"GET\", \"https://api.xholic.ai/v1/free-tools/engagement-calculator?followersCount=1&impressions=1&likes=1&replies=1&reposts=1&quotes=1\", nil)\n\treq.Header.Set(\"Authorization\", \"Bearer \"+os.Getenv(\"XHOLIC_API_KEY\"))\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\tfmt.Println(string(body))\n}"},{"lang":"php","label":"PHP","source":"<?php\n$ch = curl_init(\"https://api.xholic.ai/v1/free-tools/engagement-calculator?followersCount=1&impressions=1&likes=1&replies=1&reposts=1&quotes=1\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('XHOLIC_API_KEY')],\n]);\n$result = json_decode(curl_exec($ch), true);\necho $result['summary'];"},{"lang":"ruby","label":"Ruby","source":"require \"net/http\"\nrequire \"json\"\n\nuri = URI(\"https://api.xholic.ai/v1/free-tools/engagement-calculator?followersCount=1&impressions=1&likes=1&replies=1&reposts=1&quotes=1\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"Authorization\"] = \"Bearer #{ENV.fetch(\"XHOLIC_API_KEY\")}\"\nres = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }\nputs JSON.parse(res.body)[\"summary\"]"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","summary","data"],"properties":{"ok":{"type":"boolean","enum":[true]},"summary":{"type":"string","description":"One or two readable sentences about the result."},"data":{"description":"The result. Its shape depends on the action."},"ids":{"type":"object","additionalProperties":true},"next":{"type":"array","items":{"type":"string"}},"creditsCharged":{"type":"number"},"dryRun":{"type":"boolean"}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message","scope"],"properties":{"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_CREDENTIAL","SCOPE_MISSING","ROLE_NOT_PERMITTED","ACCOUNT_NOT_FOUND","SUBSCRIPTION_REQUIRED","FEATURE_NOT_INCLUDED","APP_ONLY","INVALID_INPUT","NOT_FOUND","CONFLICT","CREDITS_CONFIRMATION_REQUIRED","INSUFFICIENT_CREDITS","RATE_LIMITED","IDEMPOTENCY_KEY_REUSED","IDEMPOTENCY_IN_PROGRESS","X_DATA_LIMIT_REACHED","UPSTREAM_UNAVAILABLE","INTERNAL_ERROR"]},"message":{"type":"string"},"scope":{"type":"string","enum":["account","platform"]},"retryAfterSeconds":{"type":"integer"},"details":{}}}}}}}}},"parameters":[{"name":"followersCount","in":"query","required":true,"schema":{"type":"integer","minimum":0,"maximum":1000000000},"example":1},{"name":"impressions","in":"query","required":true,"schema":{"type":"integer","minimum":0,"maximum":10000000000},"example":1},{"name":"likes","in":"query","required":true,"schema":{"type":"integer","minimum":0,"maximum":1000000000},"example":1},{"name":"replies","in":"query","required":true,"schema":{"type":"integer","minimum":0,"maximum":1000000000},"example":1},{"name":"reposts","in":"query","required":true,"schema":{"type":"integer","minimum":0,"maximum":1000000000},"example":1},{"name":"quotes","in":"query","required":true,"schema":{"type":"integer","minimum":0,"maximum":1000000000},"example":1},{"name":"account","in":"query","required":false,"schema":{"description":"X account to act on, as @handle. Leave it out to use the connection's default account.","type":"string","minLength":1,"maxLength":64},"description":"X account to act on, as @handle. Leave it out to use the connection's default account."}]}}}}
