Developer API
Programmatic access to the Boatwork contractor network. Search and filter marine service professionals by specialty, location, and rating.
Authentication
All authenticated requests use a Bearer token in the Authorization header. Public API keys begin with bw_public_.
curl https://boatwork.co/api/v1/public/contractors/search \
-H "Authorization: Bearer bw_public_your_key_here" \
-G --data-urlencode "q=yacht detailing"Get your API key from your developer console → API Keys or — if you’re an AI agent — self-register (no human in the loop, see below).
Rate Limits
Public API keys are limited to 500 requests per 24-hour rolling window. When the limit is exceeded the API returns 429 Too Many Requests with a Retry-After header indicating seconds to wait.
Need higher limits? Questions? Sign in and use the feedback form, or email support@boatwork.co.
For AI Agents
Self-register, get a working API key in one POST, no human gate.
/api/agents/registerCreates an agent identity (a User row with isAgent = true) and mints the initial bw_public_* key. The plaintext key + email are returned ONCE — capture them now.
| Parameter | Type | Description |
|---|---|---|
| firstName* | string | Display first name. |
| lastName* | string | Display last name. |
| email* | string | Unique email; used for the sign-in flow. |
| password* | string | Minimum 10 characters. Hashed with argon2 server-side. |
| purpose | string | Optional free-text describing what this agent does. |
curl -X POST https://boatwork.co/api/agents/register \
-H "Content-Type: application/json" \
-d '{
"firstName": "Andi",
"lastName": "Moore",
"email": "andi-agent@example.com",
"password": "a-strong-password-of-at-least-10-chars",
"purpose": "Handles marina onboarding triage."
}'{
"success": true,
"data": {
"agent": { "id": "...", "firstName": "Andi", "lastName": "Moore", "email": "andi-agent@example.com", "isAdmin": false, "isAgent": true },
"credentials": {
"email": "andi-agent@example.com",
"apiKey": "bw_public_abcdef1234567890",
"apiKeyPrefix": "bw_public_abcdef",
"apiBase": "https://boatwork.co/api/v1/public",
"howToUse": "Send `Authorization: Bearer <apiKey>` on every request."
}
}
}Email already in use? Pick a different one (e.g. andi-agent@boatwork.co). If you legitimately own the email and want to recover, contact the admin.
/api/account/meReturns your current role + a convenience canMintAdminKeys flag. Poll this if you’re waiting for an admin to elevate you to admin tier — when isAdmin: true, your next minted key becomes a bw_live_*admin key automatically.
{
"success": true,
"data": {
"id": "...",
"firstName": "Andi",
"lastName": "Moore",
"email": "andi-agent@example.com",
"isAgent": true,
"isAdmin": false,
"canMintAdminKeys": false
}
}/api/v1/user-api-keysMint additional keys. Authenticated agents get one of two key shapes based on role: bw_public_* for public-tier users, bw_live_* for admin-tier (after elevation). Max 5 active keys for admins/agents, 2 for humans.
curl -X POST https://boatwork.co/api/v1/user-api-keys \
-H "Authorization: Bearer bw_public_your_key_here" \
-H "Content-Type: application/json" \
-d '{"name": "rotation 2026-05"}'Discovery shortcut: the same information is available machine-readable at /.well-known/agent.json, in the public OpenAPI spec at /developers/openapi.json, and as a bootstrap recipe inside /llms.txt.
Public API Endpoints
Base URL: https://boatwork.co
/api/v1/public/contractors/searchSearch active contractors by keyword, specialty, city, or state.
| Parameter | Type | Description |
|---|---|---|
| q | string | Text search on name, description, and location |
| specialty | string | Specialty slug (e.g. yacht-detailing). See /specialties endpoint. |
| city | string | City filter (case-insensitive partial match) |
| state | string | State filter (e.g. FL) |
| page | integer | Page number (1–3 max) |
| limit | integer | Results per page (max 20, default 20) |
curl "https://boatwork.co/api/v1/public/contractors/search?q=engine+repair&state=FL&limit=5" \
-H "Authorization: Bearer bw_public_your_key_here"{
"success": true,
"data": {
"contractors": [
{
"id": "clt_abc123",
"slug": "marine-engines-miami",
"name": "Marine Engines Miami",
"tagline": "Certified outboard & inboard specialists",
"location": "Miami, FL",
"geocodedCity": "Miami",
"geocodedState": "FL",
"avatarUrl": "https://example.com/logo.jpg",
"googleRating": 4.8,
"googleReviewCount": 142,
"isVerified": true,
"isClaimed": true,
"phone": "+1-305-555-0100",
"email": "info@marineenginesmiami.com",
"websiteUrl": "https://marineenginesmiami.com",
"specialities": [
{ "id": "sp_1", "name": "Engine Repair", "slug": "engine-repair" }
]
}
],
"pagination": {
"page": 1,
"limit": 5,
"total": 38,
"totalPages": 3
}
}
}/api/v1/public/contractors/geo-searchFind contractors within a radius of a point, or within a bounding box. Returns distance from the search point (point mode only).
| Parameter | Type | Description |
|---|---|---|
| lat | float | Latitude of search point (point mode) |
| lng | float | Longitude of search point (point mode) |
| radius | float | Search radius in miles (default 30, point mode) |
| minLat | float | Minimum latitude (bbox mode) |
| maxLat | float | Maximum latitude (bbox mode) |
| minLng | float | Minimum longitude (bbox mode) |
| maxLng | float | Maximum longitude (bbox mode) |
| specialtySlug | string | Filter by specialty slug |
| minRating | float | Minimum Google rating (e.g. 4.0) |
| limit | integer | Max results (default 100, max 500) |
curl "https://boatwork.co/api/v1/public/contractors/geo-search?lat=25.77&lng=-80.19&radius=20" \
-H "Authorization: Bearer bw_public_your_key_here"/api/v1/public/contractors/:slugReturns a full public profile for a contractor by slug, including photos, videos, reviews, and badges.
curl "https://boatwork.co/api/v1/public/contractors/marine-engines-miami" \
-H "Authorization: Bearer bw_public_your_key_here"{
"success": true,
"data": {
"id": "clt_abc123",
"slug": "marine-engines-miami",
"name": "Marine Engines Miami",
"about": "Full-service marine engine repair and maintenance...",
"tagline": "Certified outboard & inboard specialists",
"phone": "+1-305-555-0100",
"email": "info@marineenginesmiami.com",
"location": "Miami, FL",
"city": "Miami",
"state": "FL",
"logoUrl": "https://example.com/logo.jpg",
"isVerified": true,
"isClaimed": true,
"rating": 4.8,
"reviewCount": 142,
"specialties": [
{ "id": "sp_1", "name": "Engine Repair", "slug": "engine-repair" }
],
"photos": [],
"videos": [],
"reviews": [],
"badges": ["Top Rated"],
"social": {
"facebook": null,
"instagram": "https://instagram.com/marineenginesmiami",
"linkedin": null,
"youtube": null
},
"yearEstablished": 2015,
"updatedAt": "2024-03-15T00:00:00.000Z"
}
}/api/v1/public/contractors/specialtiesReturns all available specialty categories with their IDs and slugs. Use the slug value in search and geo-search filters.
curl "https://boatwork.co/api/v1/public/contractors/specialties" \
-H "Authorization: Bearer bw_public_your_key_here"{
"success": true,
"data": {
"specialties": [
{ "id": "sp_1", "name": "Engine Repair", "slug": "engine-repair" },
{ "id": "sp_2", "name": "Yacht Detailing", "slug": "yacht-detailing" },
{ "id": "sp_3", "name": "Marine Electrical", "slug": "marine-electrical" }
]
}
}Error Responses
All errors return a consistent JSON shape with an HTTP status code.
Error format
{
"success": false,
"error": "string — machine-readable error code",
"details": "string — human-readable explanation (when available)"
}| Parameter | Type | Description |
|---|---|---|
| 400 | Bad Request | Missing or invalid query parameters (e.g. invalid lat/lng, unknown slug). |
| 401 | Unauthorized | Bearer token is missing, malformed, or has been revoked. |
| 404 | Not Found | The requested contractor slug or ID does not exist. |
| 429 | Too Many Requests | Daily rate limit exceeded. Check the Retry-After header for seconds until reset. |
| 500 | Server Error | Unexpected internal error. If this persists, contact support@boatwork.co. |
{
"success": false,
"error": "Invalid or inactive API key"
}{
"success": false,
"error": "Contractor not found"
}{
"success": false,
"error": "Daily rate limit of 500 requests exceeded"
}429 responses include a Retry-After header with the number of seconds to wait before retrying.
Acceptable Use
By using the Boatwork API you agree to the following:
- Use the API for lawful purposes only. Do not redistribute raw data in bulk or build a competing contractor directory.
- Do not attempt to circumvent rate limits, scrape data beyond the pagination caps, or use automated tools to harvest contact information.
- Attribute data to Boatwork when displaying contractor profiles or ratings publicly (e.g. "Data from Boatwork").
- Keep your API key confidential. You are responsible for all activity under your key.
- Boatwork reserves the right to revoke keys that violate these terms or negatively impact platform performance.
Full terms at boatwork.co/terms-of-use. Questions? Email support@boatwork.co.
Ready to build?
Get your API key from the developer console and start integrating the Boatwork contractor network into your application today.