Developers · planned contracts
Bobby DB is an API-first product
Implementation status
No API is deployed. There is no base URL serving traffic, no key issuance, no metering and no MCP endpoint. Every request, response and header below is a planned contract, and every credential in an example is unmistakably fake.
Future base URL
One versioned prefix. A breaking change becomes a new version rather than a silent change to an existing one.
Planned base URL
https://bobbydb.com/api/v1
Not routable today. The versioned API namespace is reserved and is not implemented in this phase.
Example credential
bdb_public_example_replace_me
A deliberately fake placeholder. Replace it with your own key once key issuance exists. Keys always travel in a header, never in a URL.
Planned request mechanics
The behaviours a client can design against once the API is built.
- API keysPlanned
- Every request, including reads of free public data, will carry a key in an Authorization header. Keys are never accepted in a URL, a query string or a path segment, because URLs end up in logs, referrers and browser history.
- Read and write scopesPlanned
- A key is issued with read scope or write scope. A read key can list and fetch releases; a write key can create drafts, run imports and request releases. Publication still requires human review.
- Current versus pinned releasePlanned
- Without a release parameter, a read follows the collection's current release. With one, the read is pinned to an exact immutable version and never changes underneath a build.
- Cursor paginationPlanned
- Lists are paged by opaque cursor rather than numeric offset, so a page stays stable while a collection grows and a client can resume exactly where it stopped.
- Batch readsPlanned
- Several keys can be fetched in one request instead of a request per key, which is the common shape when a product boots and needs many reference values at once.
- ETag and If-None-MatchPlanned
- Release reads are designed to be strongly cacheable. A client stores the ETag and revalidates; an unchanged release answers with a not-modified response and no body.
- Idempotency keysPlanned
- Retryable writes accept a client-supplied idempotency key so a network retry cannot duplicate an import or a draft change.
- Request IDsPlanned
- Every response carries a request identifier. Quoting it lets a support conversation refer to one exact request instead of a description of one.
- Rate limitsPlanned
- Limits are applied per workspace and per key, and are designed to answer with an explicit rate-limit status and retry guidance rather than a silent failure.
- MCPPlanned
- The MCP endpoint exposes the same governed reads to AI agents, under the same keys, scopes, pinning and limits as REST. It is a delivery surface, not a second permission model.
Copyable examples
Placeholders only. These commands describe the intended contract and will not succeed against anything today.
curl "https://bobbydb.com/api/v1/collections/example-collection/entries?limit=100" \
-H "Authorization: Bearer bdb_public_example_replace_me"Cursor pagination; the key stays in the Authorization header.
curl "https://bobbydb.com/api/v1/collections/example-collection/entries?release=example-release-version" \
-H "Authorization: Bearer bdb_public_example_replace_me"A pinned read is reproducible: the release content can never change.
curl -i "https://bobbydb.com/api/v1/collections/example-collection/entries" \
-H "Authorization: Bearer bdb_public_example_replace_me" \
-H 'If-None-Match: "example-etag-value"'An unchanged release is designed to answer 304 with no body.
curl -X POST "https://bobbydb.com/api/v1/collections/example-collection/entries:batch" \
-H "Authorization: Bearer bdb_public_example_replace_me" \
-H "Content-Type: application/json" \
-d '{"keys":["example.first.key","example.second.key"]}'Fetch several keys in one round trip instead of one request per key.
curl -X POST "https://bobbydb.com/api/v1/collections/example-collection/drafts/entries" \
-H "Authorization: Bearer bdb_public_example_replace_me" \
-H "Idempotency-Key: example-idempotency-key-0001" \
-H "Content-Type: application/json" \
-d '{"key":"example.first.key","value":{"example":true}}'The idempotency key makes a retry safe after a timeout.
{
"error": {
"code": "unprocessable",
"message": "Entry value does not satisfy the collection schema.",
"request_id": "example-request-id-0001"
}
}Every error is designed to carry a stable code and the request ID.
Error taxonomy
Stable machine-readable codes, so a client branches on a code rather than parsing prose.
| Code | HTTP | Meaning |
|---|---|---|
| invalid_request | 400 | The request shape, parameters or body failed validation. |
| unauthenticated | 401 | No key was supplied, or the key is unknown or revoked. |
| forbidden | 403 | The key is valid but its scope or workspace does not allow this action. |
| not_found | 404 | The workspace, collection, release or key does not exist for this caller. |
| conflict | 409 | The write conflicts with current state, for example a competing release. |
| unprocessable | 422 | The content is well-formed but fails the collection's schema. |
| rate_limited | 429 | The per-key or per-workspace limit was exceeded; retry guidance included. |
| internal_error | 500 | An unexpected server fault. The request ID identifies the occurrence. |
REST and MCP, one governance model
MCP is an additional delivery surface over the same releases, keys, scopes and limits — not a shortcut around them.
What MCP will add
PlannedAgent-friendly discovery of collections and releases, so an agent can find the right reference data and read a pinned version without bespoke integration code.
What MCP will not change
PlannedAuthorization, metering, rate limits, visibility and immutability are identical. An agent cannot see a private collection its key does not cover.