BoardBid API v1

The BoardBid API is the pricing infrastructure layer for the corrugated packaging industry. This reference documents every public endpoint, schema, and operational detail you need to integrate.

Base URL: https://boardbid.io/api (routed to Supabase Edge Functions)

Current version: v1.0.0 · Stable

Auth: Bearer token in Authorization header

Content type: application/json for all POST bodies

Introduction

BoardBid turns natural-language corrugated packaging quote requests into structured, priced, trackable offers. The API has three core endpoints:

  • POST /v1/parse-quote — converts free-form text into a ParsedQuote object
  • POST /v1/price-quote — converts a ParsedQuote into a priced offer (beta)
  • GET /v1/health — service health check

The same API powers the BoardBid web app (boardbid.io/app), the mobile experience, and any partner integration. There is no private or "premium" API path — what the web app can do, you can do.

Quick start

The fastest way to see what the API returns is to call it. Get an API key from boardbid.io/app (free tier includes 500 parse calls per month), then:

curl -X POST https://boardbid.io/api/v1/parse-quote \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-boardbid-client: my-app-v1" \
  -d '{"text": "RSC 15x10x5 32ECT 871 qty for QEP"}'

Expected response:

{
  "api_version": "1.0.0",
  "request_id": "req_lxyz123_abc",
  "parse": {
    "type": "RSC",
    "length": 15,
    "width": 10,
    "depth": 5,
    "ect": 32,
    "wall": null,
    "quantity": 871,
    "customer": "QEP",
    "joint": null
  },
  "confidence": 0.98,
  "notes": null,
  "trace": {
    "model": "claude-sonnet-4-5",
    "latency_ms": 823,
    "claude_ms": 810,
    "regex_agreement": {
      "fields_regex_matched": 7,
      "fields_agreed": 7,
      "disagreements": []
    },
    "input_tokens": 320,
    "output_tokens": 85
  }
}

Authentication

Every request must include a Bearer token in the Authorization header:

Authorization: Bearer YOUR_API_KEY

API keys are issued from your BoardBid account. Each key:

  • Is scoped to a single tenant (your organization)
  • Can be rotated at any time without downtime (multiple active keys per tenant)
  • Inherits tenant-level permissions via row-level security on the backend database
  • Is logged on every request for audit purposes

Never put a service role key in client-side code. Service role keys bypass row-level security and should only ever be used in server-side integrations. Use the standard API key (anon JWT) for browser and mobile clients.

Client identification

Include the x-boardbid-client header to identify your integration in logs and analytics:

x-boardbid-client: acme-erp-v2

Recommended format: <product>-<environment>-<major-version>. This header is not used for authorization, only for observability. It appears in the client column of our request logs, which makes support conversations faster.

Versioning

BoardBid uses URL path versioning: /v1/parse-quote, /v1/price-quote, etc. The current stable version is v1.0.0.

What counts as a breaking change

We bump the major version (to /v2/) when any of the following change:

  • A required response field is renamed, removed, or has its type changed
  • Required request fields are added
  • An existing error code changes meaning
  • The semantic meaning of a field value changes

Non-breaking changes

These we ship without a version bump:

  • Adding optional request fields
  • Adding new response fields
  • Adding new error codes (always parse errors defensively — unknown codes may appear)
  • Adding new enum values (strict parsers beware)
  • Improving parse accuracy (outputs improve, schema is identical)

Deprecation policy

When v2 ships:

  • v1 continues to serve for at least 12 months
  • Deprecation and Sunset HTTP headers are added to v1 responses per RFC 8594
  • Email notice is sent to every API key that used v1 in the preceding 30 days
  • A migration guide is published at /docs/migrations/v1-to-v2

Request IDs

Every response includes a request_id in both the response body and the x-boardbid-request-id header. Keep this ID with every log you write about an API call — it unlocks support.

x-boardbid-request-id: req_lxyz123_abc
x-boardbid-version: 1.0.0

When filing a support issue, include the request ID. We can look up the full server-side trace of that specific call — input, output, latency, model version, which internal code path ran.

POST /v1/parse-quote

Converts free-form quote request text into a ParsedQuote object.

Request

POST /v1/parse-quote
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
x-boardbid-client: your-app-v1

{
  "text": "RSC 15x10x5 32ECT 871 qty for QEP",
  "client": "optional-client-override",
  "hints": {
    "known_customers": ["QEP", "Henderson", "CPS"],
    "default_type": "RSC"
  }
}

Parameters

FieldTypeRequiredDescription
textstring (1–2000 chars)YesThe quote request to parse. Accepts industry shorthand, natural language, or mixed.
clientstringNoClient identifier for logs. Falls back to x-boardbid-client header.
hints.known_customersstring[]NoKnown customer names or aliases. Improves customer extraction when context is ambiguous.
hints.default_typeBoxTypeNoDefault box type if the parser cannot determine one. See enums.

Response

Returns 200 OK with a ParsedQuote response body on success. See schema below.

Example

{
  "api_version": "1.0.0",
  "request_id": "req_lxyz123_abc",
  "parse": {
    "type": "RSC",
    "length": 15, "width": 10, "depth": 5,
    "ect": 32, "wall": null,
    "quantity": 871,
    "customer": "QEP",
    "joint": null
  },
  "confidence": 0.98,
  "notes": null,
  "trace": { /* see ParseTrace */ }
}

POST /v1/price-quote Beta

Converts a ParsedQuote into a priced offer. Currently returns 501 Not Implemented with the response schema fully defined — this lets you integrate against the contract today and switch to live pricing when it ships.

Request

POST /v1/price-quote
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "quote": {
    "type": "RSC",
    "length": 15, "width": 10, "depth": 5,
    "ect": 32, "quantity": 871,
    "customer": "QEP", "joint": "GLUED", "wall": null
  },
  "plant_id": "optional-plant-uuid",
  "hints": {
    "target_margin_pct": 25,
    "markup_pct": 15
  }
}

Response shape (when live)

{
  "api_version": "1.0.0",
  "request_id": "req_...",
  "price_per_piece": 0.4672,
  "total_price": 407.15,
  "breakdown": {
    "sheet_width": 11.625,
    "sheet_length": 52.25,
    "msf": 5.264,
    "board_cost": 184.22,
    "process_cost": 73.40,
    "ink_cost": 0.00,
    "tooling_amortized": 0.00,
    "indirect_cost": 51.90,
    "total_cogs": 309.52,
    "markup_applied_pct": 15,
    "margin_pct": 24.8
  },
  "trace": {
    "plant_id": "plant_abc123",
    "pricing_model_version": "v1",
    "latency_ms": 42
  }
}

GET /v1/health

Service health check. Use for uptime monitoring.

curl https://boardbid.io/api/v1/health
# No auth required
{
  "api_version": "1.0.0",
  "status": "ok",
  "services": {
    "claude": "ok",
    "database": "ok"
  },
  "timestamp": "2026-04-16T14:30:00.000Z"
}

Returns 200 when all services are healthy, 503 otherwise.

ParsedQuote schema

This is the central data structure. Every parse endpoint returns one; the price endpoint accepts one.

FieldTypeDescription
typeBoxType or nullBox style. See enums.
lengthnumber or nullInside dimension length in inches.
widthnumber or nullInside dimension width in inches.
depthnumber or nullInside dimension depth in inches.
ectinteger or nullEdge Crush Test rating. Typical: 32, 40, 44, 48, 51, 55, 61, 71.
wallWallGrade or nullWall construction. See enums.
quantityinteger or nullOrder quantity in pieces.
customerstring or nullCustomer or account name.
jointJointType or nullHow the box is assembled.

Enums

BoxType

ValueMeaning
"RSC"Regular Slotted Container — the most common corrugated box style.
"HSC"Half Slotted Container.
"FOL"Full Overlap container.
"DC RSC"Die-cut RSC — RSC with custom die-cut features.
"DC HSC"Die-cut HSC.
"DC"Die-cut box (generic).
"TUBE"Tube or sleeve-style box.
"TRAY"Tray or bliss-style.
"5PF"5-panel folder.

WallGrade

  • "SW" — single wall (most common)
  • "DW" — double wall (heavy duty)
  • "TW" — triple/twin wall (industrial)

JointType

  • "GLUED" — glued manufacturer's joint (most common)
  • "STITCHED" — stitched
  • "HOTMELT" — hot-melt adhesive

Error schema

Every error response follows a consistent shape:

{
  "api_version": "1.0.0",
  "error": {
    "code": "invalid_input",
    "message": "Field 'text' is required and must be a non-empty string",
    "request_id": "req_lxyz123_abc",
    "details": { /* optional, endpoint-specific */ }
  }
}

Error handling

HTTP status codes follow REST conventions:

StatusError codeMeaning
400invalid_jsonRequest body is not valid JSON.
400invalid_inputRequired field missing or wrong type.
400input_too_longInput exceeds the 2000-character limit.
401Missing or invalid Authorization header.
403Authenticated, but not authorized for this resource.
405method_not_allowedWrong HTTP method (use POST for most endpoints).
429Rate limit exceeded.
500configuration_errorServer misconfiguration. Rare. Contact support with request_id.
501not_implementedEndpoint stub — implementation pending (price-quote).
502upstream_errorUpstream model service failed or returned invalid output.

Best practice: Parse error codes defensively. Always check the HTTP status first, then read the error code. Treat unknown codes as generic errors — we may add new codes without a major version bump.

Rate limits

Rate limits are per API key per minute:

Tierparse-quoteprice-quotehealth
Free30/min30/minunlimited
Pro300/min300/minunlimited
EnterpriseCustomCustomunlimited

Rate-limited requests return 429 Too Many Requests with a Retry-After header. Exponential backoff with jitter is recommended.

Observability

Every request is logged server-side with:

  • Request ID, client identifier, input text
  • Full parsed output
  • Confidence score and any notes
  • Latency breakdown (total and upstream model)
  • Model version
  • Regex-validator agreement metrics
  • Input and output token counts

Logs are retained indefinitely by default. Each tenant can query their own logs via authenticated database access. Cross-tenant access is prevented by row-level security.

Glossary

Terms we use throughout the docs.

Sheet plant

A corrugated box manufacturer. Typically regional, 20–200 employees. "Sheet" refers to corrugated sheets (the pre-cut raw material sheet plants convert into finished boxes).

ECT (Edge Crush Test)

The industry-standard test for corrugated board strength. A higher ECT number means a stronger board. Common values: 32 (standard shippers), 44 (heavier), 48–71 (industrial/heavy duty).

MSF (Thousand Square Feet)

The core pricing unit for corrugated board material. Board cost is quoted per MSF, with prices varying by ECT rating, flute type, and volume tier.

RSC / HSC / FOL

Box style abbreviations. RSC (Regular Slotted Container) is the most common — a standard shipping box with flaps that meet in the middle. HSC (Half Slotted) has flaps on only one side, typically used as inserts or trays. FOL (Full Overlap) has overlapping flaps for extra strength.

Flute

The wavy corrugated medium between liners. Common flute types: C (standard), B (finer, for print), BC (double wall B + C), TW (triple wall). Affects both strength and sheet-sizing math.

Joint

How the box is assembled into its final form. Glued joints use adhesive, stitched joints use metal staples, hot-melt uses heat-activated adhesive.

Die-cut (DC)

A box with custom-cut features beyond standard slots — hand holes, tabs, windows, complex shapes. Requires a dedicated cutting die (tool), which has its own cost that's typically amortized over the order quantity.


Documentation last updated 2026-04-16. Version 1.0.0. Report issues to hello@boardbid.io.