{"_id":"@boe-ventures/platform-schemas","_rev":"2-40904c67b99f90f7651effa6dcf6a601","name":"@boe-ventures/platform-schemas","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@boe-ventures/platform-schemas","version":"0.1.0","keywords":["unofficial-api","reverse-engineering","messaging-api","browser-session","slack","linkedin","instagram","tinder","imessage","api-schemas","platform-adapters","internal-api"],"author":{"name":"Boe Ventures"},"license":"MIT","_id":"@boe-ventures/platform-schemas@0.1.0","maintainers":[{"name":"kristianeboe","email":"kristian.e.boe@gmail.com"}],"homepage":"https://github.com/boe-ventures/hydra#readme","bugs":{"url":"https://github.com/boe-ventures/hydra/issues"},"dist":{"shasum":"99a719f9a79634fac5b84a2bdc17c37004a07287","tarball":"https://registry.npmjs.org/@boe-ventures/platform-schemas/-/platform-schemas-0.1.0.tgz","fileCount":32,"integrity":"sha512-tESfduFcLGfabRlcVNvRhk9m7w48wO4l4OQvWvxH93PShb+JOTsCZ1cLtXEhAK6T0Xbr5zwWDrAnglzBaXHxjQ==","signatures":[{"sig":"MEUCIFd4i9Xluict1QZYh5lXUHmTjI5a0niL4ELGi6mni1P5AiEAzKUGOnQVm0Rctbgqgc19Q4WfhcII4YjQ/ErMO3EsZnI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":161177},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./slack":{"types":"./dist/platforms/slack.d.ts","import":"./dist/platforms/slack.js"},"./tinder":{"types":"./dist/platforms/tinder.d.ts","import":"./dist/platforms/tinder.js"},"./imessage":{"types":"./dist/platforms/imessage.d.ts","import":"./dist/platforms/imessage.js"},"./linkedin":{"types":"./dist/platforms/linkedin.d.ts","import":"./dist/platforms/linkedin.js"},"./instagram":{"types":"./dist/platforms/instagram.d.ts","import":"./dist/platforms/instagram.js"}},"gitHead":"198f057643c6629196509e8b710412d19f4108e4","scripts":{"build":"tsc","typecheck":"tsc --noEmit"},"_npmUser":{"name":"kristianeboe","email":"kristian.e.boe@gmail.com"},"repository":{"url":"git+https://github.com/boe-ventures/hydra.git","type":"git","directory":"packages/platform-schemas"},"_npmVersion":"11.11.0","description":"TypeScript schemas for unofficial messaging platform APIs — endpoints, auth patterns, rate limits, and response types for Slack, LinkedIn, Instagram, Tinder, and iMessage.","directories":{},"_nodeVersion":"25.8.0","dependencies":{"zod":"^3.24.0 || ^4.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0"},"_npmOperationalInternal":{"tmp":"tmp/platform-schemas_0.1.0_1781935473175_0.5840698830710667","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@boe-ventures/platform-schemas","version":"0.1.1","description":"TypeScript schemas for unofficial messaging platform APIs — endpoints, auth patterns, rate limits, and response types for Slack, LinkedIn, Instagram, Tinder, and iMessage.","license":"MIT","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./slack":{"types":"./dist/platforms/slack.d.ts","import":"./dist/platforms/slack.js"},"./linkedin":{"types":"./dist/platforms/linkedin.d.ts","import":"./dist/platforms/linkedin.js"},"./instagram":{"types":"./dist/platforms/instagram.d.ts","import":"./dist/platforms/instagram.js"},"./tinder":{"types":"./dist/platforms/tinder.d.ts","import":"./dist/platforms/tinder.js"},"./imessage":{"types":"./dist/platforms/imessage.d.ts","import":"./dist/platforms/imessage.js"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit"},"dependencies":{"zod":"^3.24.0 || ^4.0.0"},"devDependencies":{"@ai-sdk/anthropic":"^3.0.85","ai":"^6.0.208","typescript":"^5.8.3"},"keywords":["unofficial-api","reverse-engineering","messaging-api","browser-session","slack","linkedin","instagram","tinder","imessage","api-schemas","platform-adapters","internal-api"],"repository":{"type":"git","url":"git+https://github.com/boe-ventures/hydra.git","directory":"packages/platform-schemas"},"author":{"name":"Boe Ventures"},"gitHead":"036fd1ed2a624759ed8e1f8d198e1703d1dab2c2","_id":"@boe-ventures/platform-schemas@0.1.1","bugs":{"url":"https://github.com/boe-ventures/hydra/issues"},"homepage":"https://github.com/boe-ventures/hydra#readme","_nodeVersion":"25.8.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-Hmcsxh9Y4jB4Phn/nKL0wHYXfUk1JLfGQH9wMXttrXibbPO424MK2/BYaZfry5/mMRjx5IYTl1nz1PMIcqv33Q==","shasum":"f2524fe1dd88f575d89b922e7806380a9de75b4b","tarball":"https://registry.npmjs.org/@boe-ventures/platform-schemas/-/platform-schemas-0.1.1.tgz","fileCount":32,"unpackedSize":209220,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFh8TIyf9CIeI3nODfQWqxkN0VQQJDvaFQF/8CxBiZ0qAiEA4HW7XzqYFhk+BWa3X3ZzuakEw+uAiAM6eQWmPOqCLk4="}]},"_npmUser":{"name":"kristianeboe","email":"kristian.e.boe@gmail.com"},"directories":{},"maintainers":[{"name":"kristianeboe","email":"kristian.e.boe@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/platform-schemas_0.1.1_1782418254170_0.13362001979727434"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-20T06:04:32.974Z","modified":"2026-06-25T20:10:54.516Z","0.1.0":"2026-06-20T06:04:33.326Z","0.1.1":"2026-06-25T20:10:54.305Z"},"bugs":{"url":"https://github.com/boe-ventures/hydra/issues"},"author":{"name":"Boe Ventures"},"license":"MIT","homepage":"https://github.com/boe-ventures/hydra#readme","keywords":["unofficial-api","reverse-engineering","messaging-api","browser-session","slack","linkedin","instagram","tinder","imessage","api-schemas","platform-adapters","internal-api"],"repository":{"type":"git","url":"git+https://github.com/boe-ventures/hydra.git","directory":"packages/platform-schemas"},"description":"TypeScript schemas for unofficial messaging platform APIs — endpoints, auth patterns, rate limits, and response types for Slack, LinkedIn, Instagram, Tinder, and iMessage.","maintainers":[{"name":"kristianeboe","email":"kristian.e.boe@gmail.com"}],"readme":"# @boe-ventures/platform-schemas\n\nTypeScript types and endpoint documentation for unofficial messaging platform APIs.\n\n## What This Is\n\nA community-maintainable reference for the internal APIs that messaging platforms use under the hood. Not an API client — a **typed field manual and endpoint reference** built from reverse-engineering browser sessions.\n\nThe primary audience is humans and AI agents trying to understand what Hydra knows:\nwhich endpoints exist, how auth is extracted, what is volatile, what is risky, and\nwhich claims are live-verified versus merely documented. Some normalized types are\nconsumed directly by Hydra, but runtime SDK behavior is deliberately out of scope.\n\nEach platform module documents:\n\n- **API endpoints** — URLs, methods, required headers\n- **Authentication** — how to extract tokens from a browser session (cookies, CSRF tokens, localStorage)\n- **Raw response types** — what the API actually returns, as TypeScript interfaces\n- **Normalization** — optional functions to convert raw responses into a common shape\n- **Anti-detection** — rate limits, delay recommendations, known risks per platform\n- **Volatile IDs** — GraphQL query IDs and doc_ids that change with deploys\n- **Verification metadata** — whether an endpoint is live-verified, experimental, stale, or reference-only\n- **Changelog** — observed API changes over time\n\n## Why\n\nThese platforms don't offer official messaging/DM APIs — or lock them behind enterprise tiers. The only way to build on them is to ride the browser session, making the same API calls the web app makes.\n\nThe problem: these APIs change without notice. LinkedIn rotates GraphQL query IDs. Instagram changes doc_ids on deploy. When they change, your integration breaks.\n\nThis package documents what we've learned, in one place, with types.\n\n## Platforms\n\n| Platform | Auth Pattern | Read | Write | API Style | Stability |\n|----------|-------------|------|-------|-----------|-----------|\n| **Slack** | `xoxc-` token + `d` cookie | ✅ | ✅ | REST (internal) | Stable |\n| **LinkedIn** | CSRF from `JSESSIONID` cookie | ✅ | ⚠️ experimental | GraphQL (Voyager) | ⚠️ Volatile query IDs |\n| **Instagram** | CSRF cookie + `x-ig-app-id` | ✅ | — | REST + GraphQL | ⚠️ Volatile doc_ids, strictest detection |\n| **Tinder** | `x-auth-token` (bearer) | ✅ | ✅ | REST | Stable |\n| **iMessage** | Full Disk Access (macOS) | ✅ | ✅ | Local SQLite | Stable (schema changes across macOS versions) |\n\n## Install\n\n```bash\nnpm install @boe-ventures/platform-schemas\n```\n\n## Usage\n\n### Read confidence metadata\n\nEvery endpoint can carry `verification` metadata. Agents should inspect this before\ntreating an endpoint as product-safe:\n\n```ts\nimport { linkedinAdapter } from \"@boe-ventures/platform-schemas\";\n\nconsole.log(linkedinAdapter.endpoints.sendMessage?.verification);\n// {\n//   status: \"experimental\",\n//   lastChecked: \"2026-06-25\",\n//   source: \"external_reference\",\n//   notes: \"Endpoint family cross-checked...\"\n// }\n```\n\nStatus values:\n\n| Status | Meaning |\n|--------|---------|\n| `live_verified` | Recently exercised by Hydra or a local platform path. |\n| `documented` | Known/documented from capture or prior work, but not necessarily product-runtime. |\n| `experimental` | Plausible and useful, but needs a controlled live test before broad use. |\n| `reference_only` | Included to orient agents; do not treat as implemented. |\n| `stale` | Known or suspected to be outdated. |\n\n### Browse endpoint documentation\n\n```ts\nimport { linkedinAdapter, slackAdapter } from \"@boe-ventures/platform-schemas\";\n\n// What endpoint does LinkedIn use for conversations?\nconsole.log(linkedinAdapter.endpoints.listConversations.urlTemplate);\n// → https://www.linkedin.com/voyager/api/voyagerMessagingGraphQL/graphql?queryId=...\n\n// What headers does it need?\nconsole.log(linkedinAdapter.endpoints.listConversations.headers);\n// → { \"csrf-token\": \"{csrfToken}\", \"x-restli-protocol-version\": \"2.0.0\", ... }\n\n// How do you extract auth tokens?\nconsole.log(linkedinAdapter.auth.sources);\n// → [{ type: \"cookie\", name: \"csrfToken\", selector: \"JSESSIONID\", ... }]\n```\n\n### Check volatile IDs\n\nWhen a platform integration breaks, check here first:\n\n```ts\nimport { linkedinAdapter } from \"@boe-ventures/platform-schemas\";\nimport { DOC_IDS } from \"@boe-ventures/platform-schemas/instagram\";\n\n// LinkedIn GraphQL query IDs (change periodically)\nconsole.log(linkedinAdapter.volatileIds);\n// → { conversations: \"messengerConversations.0d5e6...\", messages: \"messengerMessages.5846e...\" }\n\n// Instagram doc_ids (change on deploy)\nconsole.log(DOC_IDS);\n// → { inboxQuery: \"27228858046797698\", threadDetail: \"27530161873341603\" }\n```\n\n### Use raw response types\n\n```ts\nimport type { SlackBootResponse, SlackRawChannel } from \"@boe-ventures/platform-schemas/slack\";\nimport type { LinkedInRawConversation } from \"@boe-ventures/platform-schemas/linkedin\";\nimport type { TinderRawMatch } from \"@boe-ventures/platform-schemas/tinder\";\n\n// Type your own API responses\nconst response: SlackBootResponse = await fetchSlackBoot();\nconst channels: SlackRawChannel[] = response.channels;\n```\n\n### Use built-in normalization (optional)\n\nEach platform includes normalization functions that map raw responses to a common `Conversation` type. Use them or build your own:\n\n```ts\nimport { normalizeConversation } from \"@boe-ventures/platform-schemas/slack\";\nimport type { Conversation } from \"@boe-ventures/platform-schemas\";\n\nconst conversation: Conversation = normalizeConversation(rawChannel, userMap, teamId, selfId);\n```\n\n### Anti-detection reference\n\n```ts\nimport { instagramAdapter } from \"@boe-ventures/platform-schemas\";\n\nconsole.log(instagramAdapter.antiDetection);\n// → { minDelayMs: 2000, maxDelayMs: 5000, maxMessageThreads: 5,\n//     notes: \"Instagram is the STRICTEST platform...\" }\n```\n\n## Fetching a single thread (targeted pull)\n\nThe inbox/list endpoints return a **thread list with only each thread's *last*\nmessage** — not full history. To pull one conversation's messages on demand\n(e.g. lazy-loading a person's thread), call the per-thread endpoint keyed by the\nthread's id:\n\n| Platform | Endpoint | Thread key | Notes |\n|----------|----------|------------|-------|\n| **Instagram** | **REST** `GET /api/v1/direct_v2/threads/{thread_id}/` (primary) — or GraphQL `IGDSlideAsyncFetchAndInsertIGDViewerThreadQuery` (`doc_id` `27110549851904846`) | REST: long `thread_id` · GraphQL: short `thread_fbid` | ⚠️ **Don't mix the two ids.** The inbox's long `thread_id` (`340282…`) works with REST but NOT GraphQL, which wants the short `thread_fbid` (`1360…`). REST is reliable since we already hold the `thread_id`. Non-text items (story replies, reactions, shares) carry no `text` — label by `item_type`. |\n| **LinkedIn** | `messengerMessages` (Voyager GraphQL) | conversation URN `urn:li:msg_conversation:…` | URN is URL-encoded in the query `variables` |\n| **Slack** | `POST /api/conversations.history` | `channel` (`C…`/`D…`/`G…` id) | same call the inbox loop makes, for one channel |\n| **Tinder** | `GET /v2/matches?message=1` | — | matches already include recent messages inline (`message=0` returns none) |\n| **iMessage** | local `chat.db` | `chat.ROWID` / `chat_identifier` | join `chat_message_join` → `message`; text may live in `attributedBody` (streamtyped) |\n\n> ⚠️ The single most common extraction bug: reading the inbox's `last_message`\n> and assuming you have the conversation. You don't — most threads need this\n> per-thread call to actually get their messages.\n\n## Sending messages (write)\n\nWhere supported, the web client sends via the same internal API. Writes execute\nin the **browser's page context** (same origin, same session) — indistinguishable\nfrom the user. Gate them behind explicit approval.\n\nWrite endpoints are documentation unless their `verification.status` says they are\nlive-verified in the current Hydra runtime. Even then: no bulk sending, no unattended\ncampaigns, and keep human cadence.\n\n| Platform | Endpoint | Key payload | Auth |\n|----------|----------|-------------|------|\n| **Slack** | `POST /api/chat.postMessage` (multipart) | `channel`, `blocks` (`rich_text`) or `text`, `client_msg_id`, `draft_id` | `xoxc-` token + `d` cookie |\n| **LinkedIn** | `POST /voyagerMessagingDashMessengerMessages?action=createMessage` | `conversationUrn`, `mailboxUrn`, `originToken`, `trackingId`, attributed text body | CSRF from `JSESSIONID`; run same-origin in a LinkedIn tab |\n| **Tinder** | `POST /user/matches/{matchId}` | `{ message }` | `x-auth-token` |\n| **Instagram** | GraphQL `IGDirectTextSendMutation` (`doc_id` `26911679871773184`) | `ig_thread_igid` (the short `thread_fbid`), `offline_threading_id`, `text.sensitive_string_value`, `send_attribution: \"igd_web_chat_tab:in_thread\"` | `x-csrftoken` + `fb_dtsg` + `x-fb-lsd` (from page config) |\n\n## Current Coverage Notes\n\nThe normalized `Platform` union includes a few platforms that do not yet have\nfull adapter docs in this package:\n\n| Platform | Current package status |\n|----------|------------------------|\n| `whatsapp` | Normalized types are consumed by the local Baileys sidecar; adapter docs live elsewhere for now. |\n| `x` | Hydra extension has runtime work, but package docs are not promoted yet. |\n| `homi` | Hydra-specific source; not a general messaging API package entry yet. |\n| `beeper` | Intentionally adjacent, not a reverse-engineered platform API. Consider a future source-adapter note. |\n\n## Contributing\n\nWhen an API breaks:\n\n1. Open the platform in your browser → Network tab\n2. Navigate to the messaging/DM section\n3. Find the new endpoint URL, query ID, or doc_id\n4. Update the relevant file in `src/platforms/`\n5. Update `volatileIds` and add a `changelog` entry\n6. Open a PR\n\n### What to capture\n\n- **Endpoint URLs** — filter Network tab by `graphql`, `api`, `voyager`\n- **Headers** — especially CSRF tokens, app IDs, protocol versions\n- **Response shapes** — copy a response and type it\n- **Query IDs** — for GraphQL platforms, the `queryId` or `doc_id` parameter\n\n## License\n\nMIT\n\n---\n\nOriginally extracted from [Hydra](https://github.com/boe-ventures/hydra), a multi-platform conversation aggregator.\n","readmeFilename":"README.md"}