Authenticating with the Macha API

Generate API keys, choose the right scopes, and authenticate requests with Bearer tokens.

The Macha API authenticates every request with a Bearer token. Tokens are organization-scoped, scope-restricted, revocable, and never reused. There is no OAuth flow today, just static API keys that you generate from the dashboard.

Token format

API keys have a fixed prefix that identifies them as Macha tokens, followed by 32 characters of random entropy:

mka_live_jbUaWzqeKB004Gr8FIHpRPoyVOq2Yzx9
└── 9 ──┘└────────── 32 ──────────────────┘
prefix    random suffix

The prefix is what Macha uses to narrow the key lookup before doing the bcrypt compare on the suffix, this keeps key validation under a millisecond at any scale. The whole token is bcrypt-hashed at rest with a cost factor that's adjusted as compute gets cheaper. Even with full database access, Macha cannot recover the original token.

Passing the token

Send the full token in the Authorization header on every request:

GET /api/v1/agents HTTP/1.1
Host: dashboard.getmacha.com
Authorization: Bearer mka_live_jbUaWzqeKB004Gr8FIHpRPoyVOq2Yzx9
Accept: application/json

Sending the token via query string, request body, or cookie is not supported and never will be. Bearer header only.

Example: curl

curl https://dashboard.getmacha.com/api/v1/agents \
  -H "Authorization: Bearer $MACHA_API_KEY"

Example: Node.js (fetch)

const res = await fetch('https://dashboard.getmacha.com/api/v1/agents', {
  headers: {
    'Authorization': `Bearer ${process.env.MACHA_API_KEY}`,
  },
});
const json = await res.json();

Example: Python (requests)

import os, requests

r = requests.get(
    'https://dashboard.getmacha.com/api/v1/agents',
    headers={'Authorization': f'Bearer {os.environ["MACHA_API_KEY"]}'},
)
data = r.json()

Scopes

Every API key has a list of scopes that restrict what it can do. Scopes follow a {resource}:{action} naming convention. There is no super-scope, a key with every scope still has to list each one explicitly.

Full scope catalog

ResourceReadWriteDelete
Agentsagents:readagents:writeagents:delete
Conversationsconversations:readconversations:writeconversations:delete
Connectorsconnectors:readconnectors:writeconnectors:delete
Custom toolscustom_tools:readcustom_tools:writecustom_tools:delete
Sourcessources:readsources:writesources:delete
Chatbotschatbots:readchatbots:writechatbots:delete
Triggerstriggers:readtriggers:writetriggers:delete
Teamteam:readteam:writeteam:delete
Analyticsanalytics:read
Organizationorg:read

analytics and org are read-only resources by design, analytics is computed from underlying data (no write surface), and org settings stay dashboard-managed for now (billing, branding, etc.).

Per-endpoint scope

Each endpoint's required scope is listed in its reference page. As shorthand:

HTTP methodScope required
GET{resource}:read
POST / PATCH{resource}:write
DELETE{resource}:delete

The OpenAPI spec exposes the exact scope under x-required-scope on each operation, so SDK generators and MCP servers can warn customers about missing scopes before making the call.

Authentication failures

Two distinct failure modes:

StatusCodeMeaningFix
401unauthorizedMissing, malformed, revoked, or unknown key.Check the token. If revoked, create a new one.
403insufficient_scopeValid key, but it lacks the scope this endpoint requires.Create a new key with the missing scope.

A 403 means "this key is real, but you didn't grant it permission", not a bug in your code. Fix it by creating a new key with broader scopes (or asking the org admin to).

Key lifecycle

Create

In the dashboard at Settings → API Keys. The full token is shown once at creation time. Macha cannot show it again, copy it immediately into your secret store.

Use

Passed as a Bearer token on every request. Macha updates the key's last_used_at timestamp asynchronously so the dashboard can show stale-key warnings, but this is fire-and-forget, your request latency is not affected.

Revoke

Click revoke in the dashboard. The key is marked inactive immediately; any further requests get 401 unauthorized. The audit history of what the key did is retained.

Rotate

Macha doesn't support in-place rotation today. The rotation pattern is:

  1. Create a new key with the same scopes as the old one
  2. Update your integration to use the new key
  3. Verify the new key is working (check logs / dashboard's last_used_at)
  4. Revoke the old key

This is overlap rotation, both keys are valid during the transition, then the old one is cut. Cleaner than in-place rotation; harder to lock yourself out.

Security best practices

  • Use environment variables. Never commit a key to source control. Macha scans public GitHub for the mka_live_ prefix and will revoke leaked keys automatically.
  • One key per integration. Don't share a key across multiple services, if one leaks, you can revoke without breaking the others.
  • Smallest scope that works. An "agent reader" integration shouldn't have agents:write. Scope keys tightly.
  • Log request_id on errors. Macha can trace any request by its ID. Support is impossible without it.
  • Rotate regularly. Six months is a reasonable cadence. The overlap rotation pattern above makes it cheap.

What Macha sees

Every authenticated request is associated with the API key's organization. The key does not impersonate a user, resources created via the API show up in audit logs as "created via API key <key label>" rather than tied to a specific person.

If you need per-user attribution, create one key per user and label it accordingly. Macha treats each key as a distinct identity for audit purposes.

🔒
Treat keys like passwords

Anyone with your key has full org-level access at the scopes you granted. Store keys in a proper secrets manager (1Password, AWS Secrets Manager, Doppler, etc.), not in .env files checked into Git.

© 2026 AGZ Technologies Private Limited