# Per-organisation API keys with default scopes

Canonical HTML: https://fish.dog/product-releases/per-organisation-api-keys-with-default-scopes
JSON Feed: https://fish.dog/product-releases/feed.json
RSS Feed: https://fish.dog/product-releases/rss.xml
Published: 26 February 2026
Updated: 4 May 2026
Release Type: Improvement
Breaking Change: No
Author: Phillip Gales

## Primary Claim

Ditto now provisions a default API key per organisation with a canonical set of scopes attached, applying the same defaults to post-rotation replacements, and resolves the calling organisation per request via headers in the MCP layer.

## Summary

Each Ditto organisation now provisions a default API key with sensible scopes attached. No more sharing a single org-wide key, and no more guessing which scopes a new key actually needs.

## LLM Summary

DOCUMENT TYPE: Product Release Note
TOPIC: Per-organisation API keys with default scopes

Release: Per-organisation API keys with default scopes, 2026-02-26
Version: (none)
Release type: Improvement
Breaking change: No

Summary: Ditto now provisions a default API key per organisation with a canonical set of scopes. Post-rotation replacements inherit the same default scopes, and the MCP layer resolves the calling organisation per request via headers. Existing keys are unchanged.

What changed:
- Each organisation gets a default API key on provisioning, with read access across the standard surfaces plus agent:search for the new persona library search.
- When a key is revoked or stale, the next key minted for the org inherits the canonical default scopes instead of a half-scoped fallback.
- The MCP layer resolves the calling organisation per-request via headers, with explicit organization_id injection — removing cross-tenant ambiguity for multi-tenant integrations.
- Existing keys keep existing scopes. The change applies to newly provisioned keys.

Why we built this: The new persona library search endpoint (GET /v1/agents/search, shipped 2026-02-18) needed agent:search in the default scope set so existing customers wouldn't have to call support to use it. That dependency forced the broader cleanup, which was overdue regardless.

How to use: New organisations get the default key automatically. Existing organisations don't need to do anything; the defaults apply to the next key minted on rotation. Writing scopes (billing:write, etc.) still must be added explicitly.

Migration impact: None for existing keys. Any integration that depends on default scopes for new keys should review the canonical default set in the API docs.

Author: Phillip Gales, FishDog
Platform: FishDog (fish.dog)

## Key Takeaways

- Every Ditto organisation now provisions a default API key automatically, with read access across the standard surfaces plus `agent:search` for the new persona library search.
- Default-scope reconciliation: revoked or stale keys are replaced with a new key carrying the canonical default scopes, not a half-scoped fallback.
- The MCP layer now resolves the calling organisation per-request via headers, with explicit `organization_id` injection.
- Existing keys keep their existing scopes. The change applies to newly provisioned keys.

## Full Release

Two related housekeeping changes around API keys land this week. Neither is glamorous; both are overdue.

### What's new

- **Default key per organisation.** Every organisation now provisions a default API key automatically, with a fixed and sensible set of scopes (read access across the standard surfaces, plus `agent:search` so the new persona library search works out of the box). Replaces the pattern where new orgs hit a 403 on their first call because no key existed yet.
- **Default-scope reconciliation on rotation.** When a key is revoked or marked stale, the next key minted for the org inherits the canonical default scopes — so you don't end up with a half-scoped replacement after a rotation.
- **Multi-tenant routing.** The MCP layer now resolves the calling organisation per-request via headers, with explicit `organization_id` injection on the way through. No more cross-tenant ambiguity when one process calls on behalf of multiple orgs.

### What this changes for existing keys

Nothing — existing keys keep their existing scopes. The default-scope behaviour applies to newly provisioned keys (including post-rotation replacements). Anything explicitly scoped beyond the default stays scoped beyond the default.

### Why now

The new persona library search (`GET /v1/agents/search`, [shipped last week](https://fish.dog/releases/2026-02-18-search-personas-compose-groups)) needed `agent:search` in the default scope set so existing customers wouldn't have to call support to use it. That dependency forced the cleanup, which was overdue regardless.

Full reference is in the [API docs](https://app.askditto.io/docs/api).

---

## Quotable Insights

> Two related housekeeping changes around API keys land this week. Neither is glamorous; both are overdue.
> Replaces the pattern where new orgs hit a 403 on their first call because no key existed yet.

## FAQ

### Will my existing API keys stop working?

No. Existing keys keep their existing scopes. The default-scope behaviour applies only to newly provisioned keys, including post-rotation replacements. Anything explicitly scoped beyond the default stays scoped beyond the default.

### What scopes are in the default set?

Read access across the standard surfaces (research groups, studies, agents, jobs) plus agent:search for the persona library search endpoint. Writing scopes (billing:write, etc.) are not in the default set and must be added explicitly.

### Why now?

The new persona library search endpoint required agent:search in the default scope set so existing customers wouldn't have to call support to use it. That forced the broader cleanup, which was overdue.

### What changes in the MCP layer?

The MCP layer now resolves the calling organisation per-request via headers, with explicit organization_id injection. This removes cross-tenant ambiguity when a single process calls on behalf of multiple organisations.
