Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Bucky Public Coverage API
version: 1.2.0
description: 'Public, developer-facing subset of the Bucky API. Curated via the default-deny allowlist in scripts/generate-openapi.ts (BUC-1216).
## Versioning and deprecation
Versions live in the URL path. Every public operation sits under an explicit
version prefix (`/api/v1`, `/api/marketplace/v2`); there is no unversioned
public surface, and no version is selected by header or query parameter.
Within a version we only make additive changes: new endpoints, new optional
request fields, and new response fields. Removing a field, narrowing a type,
tightening validation, or changing an error `code` requires a new version
prefix.
Retirement is signalled on the response, not only in release notes. A
deprecated operation returns `Deprecation` (RFC 9745) with the date the
deprecation took effect, and `Sunset` (RFC 8594) with the date it stops
answering. `Link: ; rel="deprecation"` points at the migration note.
Removal dates are operation-specific. Read the Sunset header and migration note.
`X-Bucky-API-Version` on every response reports the deployed API version.'
servers:
- url: https://buckybuild.com
description: Production
- url: http://localhost:3000
description: Local development
security:
- bearerAuth: []
tags:
- name: Coverage
description: Operations under `coverage`.
paths:
/api/v1/coverage/divisions:
get:
summary: Discover supported places
operationId: GetApiV1CoverageDivisions
tags:
- Coverage
description: Free discovery of catalogue divisions by name (`q`) or point (`lat`+`lng`). Returns the slug that `GET /api/v1/coverage/divisions/{slug}` needs, so callers never guess an identifier. Anonymous allowed; `site:read` keys accepted. Cursor-paginated by slug. An empty list means not found in the catalogue, not uncovered. Uses the `PUBLIC_READ` bucket.
security:
- apiKeyAuth: []
- bearerAuth: []
- {}
parameters:
- name: q
in: query
required: false
schema:
type: string
minLength: 2
maxLength: 100
description: Place name to search.
- name: lat
in: query
required: false
schema:
type: number
minimum: -90
maximum: 90
description: 'With lng: the division containing the point.'
- name: lng
in: query
required: false
schema:
type: number
minimum: -180
maximum: 180
description: With lat. Not combinable with q or cursor.
- name: live
in: query
required: false
schema:
type: boolean
description: Only live (true) or only not-live (false) divisions.
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 50
default: 25
description: Page size.
- name: cursor
in: query
required: false
schema:
type: string
description: meta.pagination.cursor from the previous page.
responses:
'200':
description: Catalogue divisions with the slug that coverage/divisions/{slug} accepts. Free. An empty list means not in the catalogue, not uncovered.
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/CoverageDivisionList'
'400':
description: Validation or client error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'401':
description: Authentication required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'403':
description: Insufficient permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'404':
description: No such resource, or no such route under this version prefix.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'429':
description: 'Rate limit exceeded (`code: RATE_LIMIT_EXCEEDED`, `retryable: true`). Honour `Retry-After` (seconds). `details.retry_after_ms` is the retry delay in milliseconds; `details.bucket` identifies the bucket.'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
/api/v1/coverage/divisions/{slug}:
get:
summary: Get coverage for a geo division
operationId: GetApiV1CoverageDivisionsByslugBy
tags:
- Coverage
description: Free coverage card for one division by slug. Anonymous allowed. Drops internal onboarding ops fields. Not a coordinate lookup — use `GET /api/geo/coverage-status` for a point. Uses the `PUBLIC_READ` bucket.
security:
- apiKeyAuth: []
- bearerAuth: []
- {}
parameters:
- name: slug
in: path
required: true
schema:
type: string
minLength: 1
maxLength: 200
example: ca-on-toronto
description: Catalogue slug, not a division UUID or a city name.
responses:
'200':
description: Public coverage card. Free; eligibilityKnown=false means unknown, not uncovered.
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/DivisionCoverage'
'400':
description: Validation or client error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'401':
description: Authentication required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'403':
description: Insufficient permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'404':
description: No such resource, or no such route under this version prefix.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
'429':
description: 'Rate limit exceeded (`code: RATE_LIMIT_EXCEEDED`, `retryable: true`). Honour `Retry-After` (seconds). `details.retry_after_ms` is the retry delay in milliseconds; `details.bucket` identifies the bucket.'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
RateLimit:
description: Current quota state as structured fields, e.g. `"public_read";r=29;t=54` — `r` is requests remaining, `t` is seconds until the window resets.
schema:
type: string
RateLimit-Policy:
description: The quota and window for this bucket, e.g. `"public_read";q=30;w=60` — `q` requests per `w` seconds.
schema:
type: string
RateLimit-Limit:
description: Requests permitted in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests left in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the window resets. Delta-seconds, not a timestamp.
schema:
type: integer
X-Bucky-API-Version:
description: Deployed build version; the URL fixes the contract major.
schema:
type: string
components:
schemas:
ErrorResponse:
type: object
title: ErrorResponse
required:
- error
- code
- category
- status
- retryable
- requestId
- supportId
properties:
error:
type: string
description: Human readable error message.
code:
type: string
description: Stable machine readable error code. Match on this, never on the message text.
examples:
- AUTH_REQUIRED
- INVALID_REQUEST
- NOT_FOUND
- RATE_LIMIT_EXCEEDED
- ANALYSIS_FAILED
- INTERNAL_ERROR
category:
type: string
description: Coarse class of failure, for routing and metrics.
enum:
- AUTHENTICATION
- AUTHORIZATION
- VALIDATION
- NOT_FOUND
- RATE_LIMIT
- CONFLICT
- NETWORK
- SERVER
- UNKNOWN
status:
type: integer
description: HTTP status, repeated in the body for transport-agnostic clients.
retryable:
type: boolean
description: Whether retrying the identical request can succeed. `false` means fix the request; do not back off and retry.
userMessageKey:
type: string
description: i18n key for a message safe to show an end user.
supportId:
type: string
description: Short reference to quote to support, e.g. `SUP-B1F8ACF9`.
requestId:
type: string
minLength: 1
description: Correlates this response with our server logs.
details:
description: Optional structured error details.
oneOf:
- type: string
- type: object
additionalProperties: true
- type: array
items: {}
- type: 'null'
DivisionCoverage:
$schema: https://json-schema.org/draft/2020-12/schema
type: object
properties:
geoDivision:
type: object
properties:
id:
type: string
name:
type:
- string
- 'null'
slug:
type:
- string
- 'null'
regionName:
type:
- string
- 'null'
countryCode:
type:
- string
- 'null'
publicTier:
type:
- string
- 'null'
required:
- id
- name
- slug
- regionName
- countryCode
- publicTier
additionalProperties: false
catalogueStatus:
type:
- string
- 'null'
publicTier:
type:
- string
- 'null'
onboardingStatus:
type: string
isLive:
type: boolean
resolutionStatus:
type: string
eligibilityKnown:
type: boolean
phase:
anyOf:
- anyOf:
- type: number
const: 0
- type: number
const: 1
- type: number
const: 2
- type: string
const: done
- type: 'null'
catalogueUpdated:
type:
- string
- 'null'
parcelSource:
type: object
properties:
supported:
type: boolean
sourceCity:
type:
- string
- 'null'
capabilities:
anyOf:
- type: object
properties:
live_proxy:
type: boolean
canWarmByPoint:
type: boolean
canWarmByPolygon:
type: boolean
authoritativeForParcels:
type: boolean
coverageNotes:
type: string
required:
- live_proxy
- canWarmByPoint
- canWarmByPolygon
- authoritativeForParcels
additionalProperties: false
- type: 'null'
required:
- supported
- sourceCity
- capabilities
additionalProperties: false
required:
- geoDivision
- catalogueStatus
- publicTier
- onboardingStatus
- isLive
- resolutionStatus
- eligibilityKnown
- phase
- catalogueUpdated
- parcelSource
additionalProperties: false
CoverageDivisionList:
$schema: https://json-schema.org/draft/2020-12/schema
type: object
properties:
data:
type: array
items:
type: object
properties:
geoDivisionId:
type: string
slug:
type: string
name:
type:
- string
- 'null'
regionName:
type:
- string
- 'null'
countryCode:
type:
- string
- 'null'
publicTier:
type:
- string
- 'null'
isLive:
type: boolean
catalogueStatus:
type:
- string
- 'null'
coveragePath:
type: string
required:
- geoDivisionId
- slug
- name
- regionName
- countryCode
- publicTier
- isLive
- catalogueStatus
- coveragePath
additionalProperties: false
meta:
type: object
properties:
pagination:
type: object
properties:
cursor:
type:
- string
- 'null'
hasMore:
type: boolean
totalCount:
anyOf:
- type: integer
minimum: -9007199254740991
maximum: 9007199254740991
- type: 'null'
required:
- cursor
- hasMore
- totalCount
additionalProperties: false
required:
- pagination
additionalProperties: false
required:
- data
- meta
additionalProperties: false
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: 'Supabase-issued user JWT: a signed-in session, or one an agent with no browser gets from https://buckybuild.com/auth.md (exchange without `resource`).'
apiKeyAuth:
type: http
scheme: bearer
bearerFormat: API key
description: Developer API key (`bk_live_…` / `bk_test_…`) minted at `/settings/developer`. Scoped; ignored on any path that is not allowlisted. See https://buckybuild.com/auth.md.