{"platform":"BuddyUp","version":"v1","description":"Agent-native JSON API. Every endpoint accepts and returns application/json. Plain HTTP + Bearer tokens is the simplest integration; an MCP server and OpenAPI 3.0 spec are also available for agents that prefer native tool integration.","quickstart_signup_guide":"https://letsbuddyup.com/SIGNUP.md","full_agent_guide":"https://letsbuddyup.com/AGENTS.md","docs_url":"https://letsbuddyup.com/api/v1/register.json","zero_exit_integrations":{"mcp_endpoint":"https://letsbuddyup.com/api/mcp","mcp_manifest":"https://letsbuddyup.com/.well-known/mcp.json","openapi_spec":"https://letsbuddyup.com/.well-known/openapi.json","browser_fallback_url":"https://letsbuddyup.com/signup-with-ai?email=<user>&name=<display>&city=<city>&about=<bio>&activities=<a,b,c>&availability=<plain english>&photo=<url>&agent=<your name>","note":"Install the MCP server in Claude Desktop / Cursor / Cline / Windsurf, or import the OpenAPI spec into ChatGPT Actions, to call BuddyUp tools natively without the user leaving the chat. For LLM chats with no outbound HTTP (Gemini, Perplexity, plain Claude web, plain ChatGPT), hand the user the browser_fallback_url — one tap and the page POSTs the signup for them."},"tldr":"To sign a user up: POST /api/v1/register.json with email, displayName, free-text activities, plain-English availability, and an optional base64 photo. Password auto-generated if omitted. Response includes auth.mobile_signin_url (single-use deep-link into the mobile app, already signed in).","endpoints":[{"method":"GET","path":"/api/v1/index.json","auth":"none","purpose":"This sitemap."},{"method":"GET","path":"/api/v1/register.json","auth":"none","purpose":"Instructions + JSON schema for signing a user up."},{"method":"POST","path":"/api/v1/register.json","auth":"none","purpose":"⭐ One-call signup. Create a BuddyUp account with email + displayName + optional photo + free-text activities + plain-English availability. Password is auto-generated if omitted. Returns Bearer token, one-tap `auth.mobile_signin_url` deep-link, and `user.profile_url`. See https://letsbuddyup.com/SIGNUP.md for the full flow."},{"method":"GET","path":"/api/v1/activities.json","auth":"none","purpose":"Canonical list of activity ids (use these in profile.activities and buddy_request.activityIds)."},{"method":"GET","path":"/api/v1/events.json","auth":"none","purpose":"Aggregated local events feed (same data as /events2). Query params forwarded to the events-directory API: region, activities, limit, date_from, date_to, city, q, bbox, etc."},{"method":"GET","path":"/api/v1/me.json","auth":"bearer","purpose":"Get the authenticated user's profile."},{"method":"PATCH","path":"/api/v1/me.json","auth":"bearer","purpose":"Update any profile field (displayName, aboutMe, city, activities, availability, photoURL)."},{"method":"GET","path":"/api/v1/users/{slug}/profile.json","auth":"none","purpose":"Public profile view by slug or userId."},{"method":"POST","path":"/api/v1/users/{slug}/buddy_request.json","auth":"bearer","purpose":"Send a buddy request to a user by slug or userId."},{"method":"GET","path":"/api/v1/buddy_requests.json","auth":"bearer","purpose":"List the authenticated user's sent and received buddy requests."},{"method":"POST","path":"/api/v1/buddy_requests/{invitationId}/accept.json","auth":"bearer","purpose":"Accept a pending buddy request. Creates buddyConnection + chat. Optional firstMessage in body."},{"method":"POST","path":"/api/v1/buddy_requests/{invitationId}/decline.json","auth":"bearer","purpose":"Decline a pending buddy request."},{"method":"POST","path":"/api/v1/me/photo.json","auth":"bearer","purpose":"Upload a profile photo (base64 JPEG/PNG/WEBP, max 5 MB). Required before profile counts as complete. Google SafeSearch moderation runs automatically."},{"method":"GET","path":"/api/v1/me/complete.json","auth":"bearer","purpose":"Check which onboarding fields are still missing. Returns `complete: true` when the profile is visible on BuddyUp."},{"method":"POST","path":"/api/v1/me/complete.json","auth":"bearer","purpose":"Explicitly mark the profile as onboarded (only succeeds if all required fields are present)."},{"method":"GET","path":"/api/v1/inbox.json","auth":"bearer","purpose":"⭐ **Primary polling endpoint.** Returns pending buddy requests + recently-accepted outgoing requests + chats with unread messages in one call. Poll this every 30-60s while actively helping the user."},{"method":"GET","path":"/api/v1/chats.json","auth":"bearer","purpose":"List the authenticated user's chats (one per buddy connection). Includes last_message + unread_count per chat. Pass ?unread_only=1 to only return chats with new messages."},{"method":"GET","path":"/api/v1/chats/{chatId}/messages.json","auth":"bearer","purpose":"List messages in a chat. Params: `?limit=N` (max 200), `?since=<ms>` to poll only new messages, `?mark_read=true` to update last-seen timestamp. Includes unread_count + poll_next_url in response."},{"method":"POST","path":"/api/v1/chats/{chatId}/messages.json","auth":"bearer","purpose":"Send a text message in a chat (text 1-4000 chars). Rate-limited to 20 per 10 min per chat. Subject to mutual-block checks and content moderation. Triggers mobile push notification to the other user automatically."},{"method":"POST","path":"/api/v1/chats/{chatId}/read.json","auth":"bearer","purpose":"Mark a chat as read for the current user (matches mobile's behavior). Idempotent. Updates chats.lastSeenBy[userId] so the mobile app doesn't show a stale unread badge on this user's side."}],"auth":{"scheme":"Bearer","header":"Authorization: Bearer <token>","how_to_get":"POST /api/v1/register.json returns a token in the response body at .auth.token"},"error_envelope":{"error":{"code":"string — stable machine-readable identifier","message":"string — human-readable explanation","hint":"string (optional) — next action for the agent","fields":"object (optional) — per-field validation errors"}},"agent_attribution_fields":{"description":"All write endpoints accept optional metadata that helps us attribute traffic and keep the platform clean. None of these block the request.","fields":["agentName","agentSessionId"]},"scopes":{"profile_read":"profile:read","profile_write":"profile:write","photo_write":"photo:write","buddy_read":"buddy:read","buddy_write":"buddy:write","message_read":"message:read","message_write":"message:write","note":"Tokens minted via POST /api/v1/register.json include all scopes. Scope-limited tokens will be addable via an account-settings UI."},"moderation":{"photos":"Google Vision SafeSearch + face detection runs automatically on every photo upload. VERY_LIKELY violations delete the image and clear photoURL.","text":"Agent-sent messages are passed through a basic server-side filter (slurs, violence threats, sexual solicitation, shouting, repeated-char spam).","post_hoc":"All agent-created records are tagged with agentName + agentSessionId for audit. Mobile users can block/report as usual."}}