CoordinateDocs
Connect · Sources
Connect

Everything that can feed your event log, how each connects, and the events it records.

Connect sources on Connections, or with configure ({"sources": [...]}) or connect_source over the API. Polled sources import recent history quietly when connected, then check on a schedule; Check now (poll_source) checks immediately.

GitHub

One click creates a private GitHub App for your deployment; install it on the repositories to watch. Pull requests, reviews, check runs, statuses, pushes, commits, and GitHub Actions workflow runs arrive by webhook. The GitHub connector also runs a readiness poller: for each open pull request it asks GitHub whether the PR is open, not a draft, mergeable, approved (or needs no review), and green, and records github.pr.readiness when that changes. Webhooks nudge it, so readiness follows within seconds.

The last 90 days are imported when repositories are added: pull requests, reviews, check results, completed Actions runs, and commits on the default branch. In a fork, only commits by the account the app is installed on are imported, and a push that syncs the fork records only the pusher's own commits, so upstream history doesn't read as yours. Commits on other branches arrive only live. If commits or runs are missing (a webhook GitHub never delivered), re-import the repository with coordinate configure '{"backfill": {"repo": "owner/name"}}': commits and runs already recorded are skipped. Imported Actions runs need the app's Actions: Read-only permission; coordinate status says when a permission is missing.

Notion

Click Connect, pick the pages and teamspaces Coordinate may read on Notion's consent screen, and you're done. (On a deployment without a Notion OAuth app, create an internal integration at notion.so/profile/integrations, paste its secret, and share pages with it instead.) Pages and database rows are recorded as they are created, edited, and archived.

Cloudflare

Create an API token (not the Global API Key) with read access to Account Settings, Workers Scripts, and Cloudflare Pages. For an account-owned token, add the account ID. Records the account audit log, Worker deploys, and Pages deployment stages.

Vercel

Paste an access token (add the team ID for a team). A built-in poller records every deployment as it queues, builds, goes live, fails, or is canceled.

Granola

Paste a grn_ API key (Business or Enterprise plan). Each meeting's notes arrive when the AI summary is ready.

Gmail

Click Connect and approve read-only access to message headers and labels in Google. Coordinate never reads message bodies. Mail from then on becomes gmail.message.received (inbox) and gmail.message.sent events with the sender, recipients, subject, snippet, labels, and thread; each thread is a subject (gmail:thread:<id>), as is each sender (email:<address>). Gmail notifies Coordinate through Google Cloud Pub/Sub within seconds of new mail, and Coordinate also checks every 10 minutes. Disconnecting revokes the grant at Google.

PostHog

Click Connect, sign in to PostHog (US or EU cloud), and pick the project to connect. Coordinate adds an HTTP webhook destination named "Coordinate" to that project, and every event PostHog captures from then on arrives in the log within seconds: $pageview as posthog.pageview, Signed Up as posthog.signed_up. The payload has the original event name, distinct_id, properties, the person (id and name), and a link to the event in PostHog; each person is a subject (posthog:person:<distinct_id>). Coordinate checks the destination every few hours and restores it if it was paused or edited. Disconnecting deletes the destination and revokes the grant. PostHog includes 10,000 destination deliveries a month for free and charges per delivery after that, so a busy project costs money on the PostHog side.

Linear

Click Connect and approve read access in Linear, or paste a personal API key (Settings → Account → Security & access). The last 30 days are imported as history. Afterwards, a one-click connection is updated within seconds: Linear notifies Coordinate of each change, and Coordinate also checks every 15 minutes in case a notification is missed. A pasted key is checked every 2 minutes. Coordinate records issues created, updated, completed, canceled, and archived (linear.issue.*) and new comments (linear.comment.created). Issue events carry the identifier, title, the first 2,000 characters of the description, state, team, project, cycle, assignee, priority, labels, and due date. Each issue is a subject (linear:issue:<id>), as are its team, project, and assignee. Disconnecting a one-click connection revokes the grant at Linear.

Todoist

Click Connect and approve read access in Todoist. Existing tasks are a silent baseline; afterwards tasks added, completed, edited, and deleted, and reminders, become events.

Web pages and feeds

Give any public https URL and a name. A built-in poller records one event per new entry of an RSS or Atom feed, or an event with the added lines when a page's text changes. Checked hourly by default.

Claude Code

Connect to get a settings.json block that points Claude Code's OpenTelemetry logs at https://usecoordinate.com/otlp. Each API call becomes one claude_code.usage event with cost and tokens.

An agent can set it up too. Create the source with coordinate configure '{"sources": [{"kind": "http", "name": "claude-code", "description": "Claude Code telemetry"}]}', which returns an ingest token (or, if the source already exists, run coordinate token claude-code for a new one). Then merge this into ~/.claude/settings.json and restart Claude Code:

json
{"env": {"CLAUDE_CODE_ENABLE_TELEMETRY": "1", "OTEL_LOGS_EXPORTER": "otlp", "OTEL_METRICS_EXPORTER": "none",
  "OTEL_EXPORTER_OTLP_PROTOCOL": "http/json", "OTEL_EXPORTER_OTLP_ENDPOINT": "https://usecoordinate.com/otlp",
  "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer <ingest token>"}}

Connections recognizes that source and won't create a second one.

Claude Managed Agents

Add https://usecoordinate.com/hooks/anthropic/<workspace>/<name> as a webhook endpoint in the Claude Console and paste its whsec_ signing secret. Session, agent, deployment, and vault changes arrive as anthropic.* events.

Your apps (HTTP)

Create an HTTP source on Connections, or with coordinate configure '{"sources": [{"kind": "http", "name": "deploys"}]}', to get an ingest token that can only append to it. It's shown once; coordinate token deploys (the create_ingest_token operation) makes another.

bash
curl -X POST https://usecoordinate.com/v1/sources/deploys/events \
  -H "Authorization: Bearer $INGEST_TOKEN" -H "content-type: application/json" \
  -d '[{"type": "deploy.finished", "producer_event_id": "deploy-481", "payload": {"service": "api", "status": "ok"}}]'

Any OpenTelemetry logs exporter can also post OTLP/HTTP JSON to https://usecoordinate.com/otlp/v1/logs with an ingest token.

Event types

GitHub

TypeWhat it records
github.pr.readinessEmitted when a pull request's readiness may have changed and the result differs from the last one. Payload: repo, number, title, url, author, head_sha, head_short, base_ref, state, draft, mergeable, review_decision, checks, ready, not_ready_reasons, observed_seq.
github.pr.<action>Pull request lifecycle passthrough: opened, reopened, edited, synchronize, ready_for_review, converted_to_draft, review_requested, review_request_removed, labeled, merged, closed, and others. Payload: repo, number, title, url, author, head_sha, base_ref, draft, state, action, sender, requested_reviewer, requested_team; opened, reopened, edited, ready_for_review, closed and merged also carry body (the description, up to 16,000 characters).
github.pr.review_<action>Review submitted, edited, or dismissed. Payload adds review.state, review.author, review.submitted_at.
github.commitOne per commit, from pushes (live, with branch) and history imports (default branch). Payload: repo, sha, branch, title, message (up to 16,000 characters), author, author_name, committed_at, url. Keyed by repo and SHA, so a commit is recorded once.
github.check.completedA check run finished. Payload: repo, name, status, conclusion, head_sha, head_branch, check_suite_id, run_id (GitHub Actions; joins github.workflow_run.* for the workflow and the event that started it), completed_at, url, app, pull_requests.
github.workflow_run.<action>A GitHub Actions workflow run was requested, started (in_progress), or completed. Payload: repo, workflow, run_id, run_number, run_attempt, check_suite_id, status, conclusion, event, branch, head_sha, title, actor, url, started_at, pull_requests. Needs the app's Actions: read permission and the Workflow run event.

Notion

TypeWhat it records
notion.page.createdA page or database row was created. Payload: page_id, title, url, parent (type, database_id, database), properties (plain values), created_by, created_time.
notion.page.updatedA page or database row was edited. Notion reports edit times to the minute, so rapid edits collapse into one. Payload as created, plus last_edited_by and last_edited_time.
notion.page.archivedA page was archived or moved to trash.
notion.database.updatedA database's title or schema changed, or it was created.

Cloudflare

TypeWhat it records
cloudflare.auditA change in the Cloudflare account from its audit log. Payload: action, result, resource_type, resource_id, actor, actor_type, interface, metadata.
cloudflare.worker.deployedA Worker deployment. Payload: script, deployment_id, author, source, message, triggered_by (deployment for code, secret for a secret change), versions, from ("audit log" when only the audit log saw it, with no versions).
cloudflare.pages.deploymentA Pages deployment reached a new stage or status. Payload: project, deployment_id, environment, stage, status, url, branch, commit_hash, commit_message.

Granola

TypeWhat it records
granola.note.createdMeeting notes are ready (Granola lists a note once its AI summary exists). Payload: note_id, title, web_url, owner, meeting (title, start, end, organiser), attendees (name, email), folders, summary (markdown).
granola.note.updatedMeeting notes were edited or re-summarized. Payload as created.

Todoist

TypeWhat it records
todoist.task.addedA task was created. Payload: task_id, content, description, project, due, priority, labels, url.
todoist.task.completedA task was checked off. Payload as added, plus completed_at.
todoist.task.updatedA task's text, due date, priority, labels, or project changed.
todoist.task.deletedA task was deleted.
todoist.reminder.addedA reminder alert was set on a task. Payload: reminder_id, task_id, task, type (absolute, relative, location), remind_at (local time, when known), minute_offset (relative: minutes before the task is due), location, url.
todoist.reminder.updatedA reminder's time or offset changed. Payload as added.
todoist.reminder.deletedA reminder was removed (Todoist also removes reminders once they fire). Payload as added.
todoist.reminder.firedA reminder went off (one-click connections only; sent by Todoist's webhook). Payload as added.

Gmail

TypeWhat it records
gmail.message.receivedA message arrived (inbox). Payload: message_id, thread_id, account, from, from_address, to, cc, subject, snippet, labels, unread, list_id, url. Headers and snippet only, never the body.
gmail.message.sentThe account sent a message. Payload as received.

PostHog

TypeWhat it records
posthog.<event>Every event captured in the PostHog project, as it is ingested: posthog.pageview for $pageview, posthog.signed_up for "Signed Up". Payload: event (the original name), distinct_id, properties, person {id, name, url}, url (the event in PostHog).

Linear

TypeWhat it records
linear.issue.createdAn issue was created. Payload: issue_id, identifier (ENG-123), title, description (first 2,000 characters), url, state, state_type (backlog, unstarted, started, completed, canceled, triage), team (key), project, cycle, assignee, creator, priority, estimate, due, labels, parent, created_at, updated_at, completed_at, canceled_at, archived_at.
linear.issue.updatedAn issue's title, description, state, assignee, priority, estimate, due date, labels, project, cycle, or parent changed. Payload as created.
linear.issue.completedAn issue moved to a completed state. Payload as created.
linear.issue.canceledAn issue moved to a canceled state. Payload as created.
linear.issue.archivedAn issue was archived. Payload as created.
linear.comment.createdSomeone commented on an issue. Payload: comment_id, body (first 2,000 characters), url, author, issue (id, identifier, title, team), created_at.

Vercel (poller)

TypeWhat it records
vercel.deployment.<state>A deployment reached a state: queued, initializing, building, ready, error, or canceled. Payload: project, deployment_id, url, state, target, creator, branch, commit_sha, commit_message, commit_author, inspector_url.

Web pages and feeds (poller)

TypeWhat it records
web.feed.itemA new entry in an RSS or Atom feed. Payload: id, title, link, published, summary, feed, url.
web.page.changedThe text of a watched page changed. Payload: url, title, added_lines (up to 40), added_count, removed_count, excerpt.

Claude Code

TypeWhat it records
claude_code.usageOne Claude Code API call: model, cost_usd, cost_microusd (integer), input/output/cache tokens, tokens_total, day (UTC), hour, session_id, user. Derived from the api_request/api_response records.
claude_code.user_promptA prompt was submitted (text only when OTEL_LOG_USER_PROMPTS=1).
claude_code.api_errorAn API request failed: status_code, error.
claude_code.api_refusalThe model declined a request.

Claude Managed Agents

TypeWhat it records
anthropic.<resource>.<event>One per webhook delivery, named after the Console event (for example anthropic.session.status_idle). Payload: resource_type, resource_id, organization_id, workspace_id, event_id.

Coordinate (source coordinate)

TypeWhat it records
trigger.firedA trigger fired. Payload: trigger, trigger_id, firing_id, reason, key (query triggers with key), event_id and event_type (event triggers), rows (query triggers).
action.succeededAn action of a firing was accepted. Payload: trigger, firing_id, action (index), kind, status_code, recorded (fields kept from the response).
action.failedAn action failed after its retries, or for good. Payload: trigger, firing_id, action, kind, status_code, error, attempts.
login.*Sign-ins: login.signed_in, login.requested, login.approved, login.denied. Payload includes a one-line summary.