Service accounts and API keys

Free workspaces can create read-only API keys for limited REST access. Pro workspaces create full service accounts for automations, CI jobs, and third-party tools that need production workspace access.

Pro plan Full service accounts are available on Pro and above. Upgrade from Billing & Plans.

Service account or personal token?

Project Feed has two kinds of API credentials. They look identical on the wire — both go in the same Authorization: Bearer header. They differ in who owns them and what happens when people come and go.

Free workspaces can create read-only API keys with projects, posts, comments, reactions, and tasks read scopes only. Pro workspaces create full service accounts with writes, media, webhooks, MCP tools, docs, canvas, and automation surfaces.

Service account

Owned by the workspace. Admins mint and rotate. Survives the creator leaving the workspace. No seat consumed. Pick this for anything that should outlive a single person: a deploy bot, a GitHub Action, a recurring sync.

Personal access token

Owned by a user, tied to a real account, capped by that user’s role. The token dies the moment the user leaves the workspace. Pick this for personal scripts, ad-hoc CLI use, or anything that genuinely belongs to one human.

Personal tokens live under Account → API tokens. Service accounts live under workspace settings.

Create a service account

  1. 1.

    Open service account settings

    Go to Settings → Service accounts. Only workspace owners and admins see this page. If you’re a member, ask an admin to create the credential and share the secret through your password manager.

  2. 2.

    Name it after the system, not the person

    Use names that survive a re-org. “CI deploy bot” ages well. “Alice’s key” does not. The name appears in audit logs, so choose something a reviewer can recognize later.

  3. 3.

    Pick the smallest scope set that does the job

    Each resource has Read / Write / None. Write includes Read. A GitHub Action that creates tasks needs tasks:write and nothing else. Don’t check boxes “just in case” — a leaked token has the exact blast radius of the scopes you gave it.

  4. 4.

    Copy the secret once

    The full secret shows once, in the create dialog. Project Feed stores a hash — nobody (including support) can read it back. Paste it straight into your secret manager (GitHub Actions secret, Vercel env var, 1Password, AWS Secrets Manager). Never commit it.

Using the secret

Send the secret as a bearer token on every request:

curl https://api.projectfeed.dev/v1/tasks \
  -H "Authorization: Bearer pf_live_..."

Read the full auth reference at API → Authentication. Scope-by-scope endpoint behavior lives at API → Scopes.

Attribute which AI client sent a write

Optional request header X-Project-Feed-Client tags API-created posts, tasks, comments, and other content with the calling client. Accepted values include codex, claude, grok, cursor, gemini, openai, and cli. The Project Feed CLI sends cli automatically; set PFEED_CLIENT (or PROJECT_FEED_CLIENT) to override it, e.g. when the CLI is driven by Claude.

curl https://api.projectfeed.dev/v1/posts \
  -H "Authorization: Bearer pf_live_..." \
  -H "X-Project-Feed-Client: codex" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"...","title":"Ship note","content":[...]}'

In the app, attributed content shows the client badge (Codex, Claude, Grok, etc.) instead of the generic API pill. The service account name still appears in the tooltip. This header is self-reported attribution, not a security boundary. Task status/field updates and checklist toggles honor the header too, so task activity rows carry the same attribution as comments and checklist additions.

Rotation and revocation

Rotate on a schedule

Rotate every 90 days if you can. From the service account row, open the menu and pick Rotate secret. The old secret stops working the moment the new one is shown. Update your secret store before closing the dialog.

Revoke when in doubt

Suspect a secret leaked into a log, a screenshot, or a repo? Revoke it. Every request using the revoked secret returns 401 immediately. You can’t un-revoke — mint a fresh one and wire it into your secret store.

Important: rotation is immediate. The previous secret stops working as soon as the new secret is shown. If you need overlap, create a second service account with the same scopes, move traffic over, then revoke the original.

Common patterns

CI deploy bot

One service account per repo or per env. Scopes: posts:write, tasks:write. The bot publishes release notes and marks shipped tasks done on every deploy.

GitHub ↔ Project Feed sync

Service account on the Project Feed side, GitHub Actions secret on the GitHub side. Scopes: tasks:write, comments:write. Closes the loop between issues and tasks.

Weekly status report

A scheduled job hits GET /v1/posts with posts:read and posts a digest to Slack. Read-only scope, so a leak can’t damage anything.

Workspace-to-workspace bridge

Mirror tasks from a partner’s workspace into your backlog via inbound webhooks. The service account isn’t even involved here — but the two surfaces are often confused, so it’s worth saying out loud.

Security

  • HTTPS only. The API rejects plain HTTP.
  • Secrets are stored as bcrypt hashes. They cannot be retrieved after creation — only rotated or revoked.
  • The workspace policy Allowed scopes caps what an admin can grant. Tighten it if you want a hard ceiling.
  • Every service account action (create, rotate, revoke, use) shows up in the audit log.

API authentication reference

Bearer header formats, error codes, and language-specific examples (curl, JS, Python).