REST API · v1

WasteBolt API

Create and manage Waste Transfer Notes programmatically. Integrate WasteBolt into your weighbridge software, ERP, or custom workflow.

4 Endpoints
API Key Auth
60 req/min
HTTPS only

Quick Start

The fastest way to explore the API is with our Bruno collection — a ready-to-run set of requests covering every endpoint, including hazardous waste, POPs, and DWT submission scenarios.

WasteBolt Bruno Collection

8 pre-built requests · all waste types · environment variables · DWT readiness examples

Download Collection
1Install Bruno (free, open source API client)
2Download and unzip the collection above, then open the folder in Bruno
3Open Environments → Production and replace your_api_key_here with your key
4Select the Production environment and run any request — check dwt_readiness in the response

Base URL

https://vfhjhirnyulkvkmukpbj.supabase.co/functions/v1

Authentication

All API requests require an x-api-key header containing your WasteBolt API key. Keys are generated from your account under Settings → Apps & Downloads. Keys are prefixed with wbsync_.

Example request header
x-api-key: wbsync_AbCdEfGhIjKlMnOpQrStUvWxYz012345

Keep your API key secret. Do not expose it in client-side code or public repositories. If a key is compromised, disable it immediately from Apps & Downloads and create a new one.

Rate Limiting

Each API key is limited to 60 requests per minute. Limits are tracked per key using a fixed 1-minute window. All responses include rate limit headers so you can monitor usage.

X-RateLimit-Limit

Max requests per window

60
X-RateLimit-Remaining

Requests left this window

47
X-RateLimit-Reset

Window reset timestamp (ISO)

2026-03-02T09:02:00Z

When the limit is exceeded you will receive a 429 response with a Retry-After header indicating seconds until reset.

429 Response
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-03-02T09:02:00.000Z
Retry-After: 23

{
  "success": false,
  "error": "Rate limit exceeded. 60 requests per minute allowed. Retry in 23s.",
  "code": "RATE_LIMIT_EXCEEDED"
}

Error Codes

All error responses share the same shape. The code field is stable and safe to use in your error handling logic.

Error response shape
{
  "success": false,
  "error": "Human readable message",
  "code": "MACHINE_READABLE_CODE"
}
CodeHTTP
NO_API_KEY401
INVALID_KEY_FORMAT401
INVALID_KEY401
KEY_DISABLED401
KEY_EXPIRED401
SUBSCRIPTION_INACTIVE403
RATE_LIMIT_EXCEEDED429
VALIDATION_ERROR422
INVALID_STATUS422
NOT_FOUND404
WTN_LOCKED409
INVALID_JSON400
INVALID_ID400
METHOD_NOT_ALLOWED405
NOTE_NUMBER_ERROR500
DATABASE_ERROR500
POST/create-wtn-api

Create a Waste Transfer Note

Creates a new WTN under your account. Returns the full note including the auto-generated note number.

Required Fields

producer_details.namestringName of the waste producer
producer_details.addressstringFull address of the producer
waste_details.waste_ewcstringEWC code e.g. "20 03 01" (asterisk for hazardous is fine, e.g. "16 06 01*")
waste_details.waste_namestringDescription of the waste
waste_details.weight_kgnumberWeight in kg — or set transfer_details.net_weight instead
transfer_details.transfer_datestringISO date e.g. "2026-03-02"

Optional Fields

carrier_detailsobjectCarrier name, address, vehicle_reg, license_no, registration_reason
consignee_detailsobjectReceiving site name, address, postcode, license_no, contact_email
note_typestring"single" (default) | "season_ticket"
statusstring"draft" (default) | "complete"

Hazardous waste — set waste_details.is_hazardous: true

These fields follow the same standard as WasteBolt's own hazardous WTN form, so notes created here submit to DWT identically.

waste_details.hazardous_property_codestring[]Required. One or more HP codes, e.g. ["HP_3","HP_14"]
waste_details.source_of_componentsstringRequired. NOT_PROVIDED | PROVIDED_WITH_WASTE | GUIDANCE | OWN_TESTING
waste_details.hazardous_componentsobject[]Required if source_of_components ≠ NOT_PROVIDED. [{ name, concentration }]
waste_details.hazardous_waste_consignment_codestringRecommended for DWT — omitting it just adds a readiness warning
waste_details.special_handling_requirementsstringOptional free text

POPs — set waste_details.contains_pops: true

POPs can apply to hazardous or non-hazardous waste — the two flags are independent.

waste_details.pops_source_of_componentsstringRequired. NOT_PROVIDED | PROVIDED_WITH_WASTE | GUIDANCE | OWN_TESTING
waste_details.pops_componentsobject[]Required if source ≠ NOT_PROVIDED. [{ code, concentration }] — code must be a valid POP code (e.g. "PFOS", "PCB")
curl -X POST https://vfhjhirnyulkvkmukpbj.supabase.co/functions/v1/create-wtn-api \
  -H "x-api-key: wbsync_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "producer_details": {
      "name": "Acme Waste Ltd",
      "address": "123 Industrial Estate, Birmingham, B1 1AA",
      "postcode": "B1 1AA"
    },
    "carrier_details": {
      "name": "Fast Carriers Ltd",
      "address": "456 Transport Road, Coventry, CV1 2BB",
      "vehicle_reg": "AB12 CDE",
      "license_no": "CBDU123456"
    },
    "consignee_details": {
      "name": "Green Recycling Ltd",
      "address": "789 Waste Park, Wolverhampton, WV1 3CC",
      "postcode": "WV1 3CC",
      "license_no": "EPR/AB1234CD/A001",
      "contact_email": "site@greenrecycling.co.uk"
    },
    "waste_details": {
      "waste_ewc": "20 03 01",
      "waste_name": "Mixed municipal waste",
      "weight_kg": 5000,
      "is_hazardous": false,
      "contains_pops": false
    },
    "transfer_details": {
      "transfer_date": "2026-03-02"
    },
    "note_type": "single",
    "status": "draft"
  }'
201 Response
{
  "success": true,
  "message": "Waste Transfer Note created successfully",
  "data": {
    "id": 1042,
    "note_number": "ACM-1042",
    "status": "draft",
    "note_type": "single",
    "created_at": "2026-03-02T09:15:32.000Z",
    "producer_details": { ... },
    "carrier_details": { ... },
    "consignee_details": { ... },
    "waste_details": { ... },
    "transfer_details": { ... }
  },
  "dwt_readiness": {
    "ready": false,
    "errors": [],
    "warnings": [
      "Carrier registration/licence number is missing — DWT submission will need carrier_details.registration_reason"
    ]
  }
}

dwt_readiness

Every successful create response includes a dwt_readiness object — the same checks WasteBolt runs before a WTN can be submitted to DEFRA's Digital Waste Tracking service. errors block DWT submission until fixed; warnings won't block submission but will prompt for a reason (e.g. no carrier registration, no consignment code) inside the app.

GET/wtn-api

List Waste Transfer Notes

Returns a paginated list of WTNs for your account, newest first. Supports filtering by status, date range, note type, DWT status, and note number search.

Query Parameters

statusstringFilter by status: draft | complete | signed
note_typestringFilter: standard | hazardous | season_ticket
dwt_statusstringFilter: pending | submitted | failed
fromdateStart date (inclusive) e.g. 2026-01-01
todateEnd date (inclusive) e.g. 2026-12-31
searchstringSearch note_number (partial match)
pageintegerPage number, default 1
limitintegerResults per page, default 20, max 100
cURL
curl "https://vfhjhirnyulkvkmukpbj.supabase.co/functions/v1/wtn-api?status=complete&from=2026-01-01&limit=20&page=1" \
  -H "x-api-key: wbsync_YOUR_KEY_HERE"
200 Response
{
  "success": true,
  "data": [ { ... }, { ... } ],
  "pagination": {
    "total": 84,
    "page": 1,
    "limit": 20,
    "total_pages": 5,
    "has_next": true,
    "has_prev": false
  },
  "filters_applied": {
    "status": "complete",
    "from": "2026-01-01"
  }
}
GET/wtn-api/:id

Get a Single WTN

Returns a single WTN by its numeric ID. Only returns WTNs belonging to your account.

idintegerThe numeric WTN ID returned when creating or listing WTNs
cURL
curl "https://vfhjhirnyulkvkmukpbj.supabase.co/functions/v1/wtn-api/1042" \
  -H "x-api-key: wbsync_YOUR_KEY_HERE"
200 Response
{
  "success": true,
  "data": {
    "id": 1042,
    "note_number": "ACM-1042",
    "status": "complete",
    "note_type": "single",
    "created_at": "2026-03-02T09:15:32.000Z",
    "dwt_status": "pending",
    "producer_details": { ... },
    "carrier_details": { ... },
    "consignee_details": { ... },
    "waste_details": { ... },
    "transfer_details": { ... }
  }
}
PATCH/wtn-api/:id

Update WTN Status

Updates the status of a WTN. Signed WTNs are locked and cannot be modified via the API.

Body Fields

statusstring"draft" | "complete" — signed WTNs return 409 WTN_LOCKED
cURL
curl -X PATCH "https://vfhjhirnyulkvkmukpbj.supabase.co/functions/v1/wtn-api/1042" \
  -H "x-api-key: wbsync_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"status": "complete"}'
200 Response
{
  "success": true,
  "message": "WTN updated successfully",
  "data": {
    "id": 1042,
    "note_number": "ACM-1042",
    "status": "complete",
    ...
  }
}

Ready to integrate?

Sign in to your WasteBolt account, head to Settings → Apps & Downloads, and generate your first API key in seconds.