Bigfoot Delivery

Legendary Performance. On Demand.

Delivery API Guide

Version 1 · For developers connecting an ordering system · Updated Oct 20, 2026

API overview

The Bigfoot Delivery API lets your system get prices for, order and track same-day deliveries in the Seattle area without going through our website.

You can:

  • Get prices. Send pickup, delivery, package and ready time. Get back every service available for that shipment, with its price and delivery deadline.
  • Place orders. Choose a service from the quote and order it. Get back a tracking number.
  • Track. Look up status and the current price by tracking number.
  • Review invoices. List your invoices and see the final price of every order on them.
Test base URL
https://test-api.bigfootdelivery.app
Production base URL
https://api.bigfootdelivery.app
Authentication
Authorization: Bearer <YOUR_API_KEY>
Format
JSON over HTTPS (TLS 1.2 or newer)
Time zone
Pacific Time. Deadlines and order times come back as ISO 8601 and as a display string.
Currency
USD
Rate limit
60 requests per minute, 2,000 per day, per key
Service area
King, Pierce and Snohomish counties.
Version
v1. Every path starts with /v1.

Getting started

  1. Get your key

    We send your API key by a one-time secure link. The link opens once, then the key is gone. Save the key in your password manager or secret store before you close the page.

    If the link expired or someone else opened it, tell us. We will issue a new key.

  2. Store it on your server

    Keep the key in an environment variable or secret store. The examples below read it from BIGFOOT_API_KEY.

  3. Get a quote

    Send the shipment details to POST /v1/quotes without a service. You get back every available service, cheapest first.

  4. Place the order

    Send the quoteId of the service you chose to POST /v1/orders within 30 minutes. You get back a tracking number. The price matches the quote.

  5. Track it

    Call GET /v1/orders/{trackingNumber} for status and current price.

Complete example

Names, phone numbers, prices and IDs below are examples. The addresses are public landmarks (Pike Place Market and the Space Needle), so the requests work as written against the test URL.

The examples use a Unix shell (macOS, Linux, or Git Bash or WSL on Windows). Set these first:

Setup
export BASE_URL="https://test-api.bigfootdelivery.app"
export BIGFOOT_API_KEY="<YOUR_API_KEY>"

1. Quote

Request
curl -X POST "$BASE_URL/v1/quotes" \
  -H "Authorization: Bearer $BIGFOOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pickup": {
      "company": "Acme Kitchen",
      "contact": "Dana Lee",
      "phone": "206-555-0100",
      "address1": "85 Pike St",
      "city": "Seattle",
      "state": "WA",
      "postalCode": "98101"
    },
    "delivery": {
      "company": "Northwind Offices",
      "contact": "Sam Ortiz",
      "phone": "206-555-0199",
      "address1": "400 Broad St",
      "city": "Seattle",
      "state": "WA",
      "postalCode": "98109"
    },
    "readyTime": "2026-12-15T09:00:00-08:00",
    "package": { "pieces": 1, "weightLb": 10, "lengthIn": 12, "widthIn": 12, "heightIn": 12 },
    "reference": "SO-10442"
  }'
Response 200
{
  "distanceMiles": 1.2,
  "readyTimeDisplay": "Tue, Dec 15, 9:00 AM PT",
  "options": [
    {
      "service": "standard",
      "serviceName": "Courier Standard",
      "description": "Delivered by end of day",
      "price": { "base": 30, "options": [], "total": 30, "currency": "USD" },
      "deliverBy": "2026-12-15T17:00:00-08:00",
      "deliverByDisplay": "Tue, Dec 15, 5:00 PM PT",
      "quoteId": "q_k3Vd8Qm2LxR7nPa1sT9wYb",
      "expiresAtDisplay": "Tue, Dec 15, 8:40 AM PT"
    },
    {
      "service": "rush",
      "serviceName": "Courier Rush",
      "description": "Delivered within 2 hours of ready time",
      "price": { "base": 40, "options": [], "total": 40, "currency": "USD" },
      "deliverBy": "2026-12-15T11:00:00-08:00",
      "deliverByDisplay": "Tue, Dec 15, 11:00 AM PT",
      "quoteId": "q_Z8mPq4Tn6Wc2Hs9Lk1Ve3R",
      "expiresAtDisplay": "Tue, Dec 15, 8:40 AM PT"
    },
    {
      "service": "direct",
      "serviceName": "Courier Direct",
      "description": "Delivered within 1 hour of ready time",
      "price": { "base": 53.5, "options": [], "total": 53.5, "currency": "USD" },
      "deliverBy": "2026-12-15T10:00:00-08:00",
      "deliverByDisplay": "Tue, Dec 15, 10:00 AM PT",
      "quoteId": "q_Hy2Nb7Xr5Fd1Gq8Jm4Ps6T",
      "expiresAtDisplay": "Tue, Dec 15, 8:40 AM PT"
    }
  ],
  "notAvailable": [
    { "service": "freight", "reason": "Freight is for pallets and shipments over 250 lb or over 60 in on a side" }
  ]
}

2. Place an order for Rush

Request
curl -X POST "$BASE_URL/v1/orders" \
  -H "Authorization: Bearer $BIGFOOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "quoteId": "q_Z8mPq4Tn6Wc2Hs9Lk1Ve3R" }'
Response 200
{
  "trackingNumber": "123456789",
  "status": "submitted",
  "service": "rush",
  "distanceMiles": 1.2,
  "price": { "base": 40, "options": [], "total": 40, "currency": "USD" },
  "deliverBy": "2026-12-15T11:00:00-08:00",
  "deliverByDisplay": "Tue, Dec 15, 11:00 AM PT"
}

3. Check status

Request
curl "$BASE_URL/v1/orders/123456789" \
  -H "Authorization: Bearer $BIGFOOT_API_KEY"

Authorization

Send your key on every request in the Authorization header:

Header
Authorization: Bearer <YOUR_API_KEY>
  • One key per company. The key identifies your account. Every order placed with it is billed to you. You never send an account ID.
  • Test and production keys are separate. You get a test key first. Email us for a production key when you're ready.
  • HTTPS only. Plain HTTP and TLS older than 1.2 are refused.
  • IP allow-list (optional). Send us the fixed IP addresses your server calls from and we will refuse your key from anywhere else.

Keep the key secret

  • Call the API from your server only. Never put the key in a browser, mobile app or anything a user can download.
  • Never put it in source code, tickets, chat or email.
  • Don't log the Authorization header.

If the key may be exposed, call or email us right away. We switch it off and send a new one by secure link. The old key stops working as soon as we revoke it.

When authorization fails

You get 401 unauthorized when the header is missing or malformed, the key is wrong, the key has been revoked, or the request came from an IP outside your allow-list. Check the header first. If it is correct, contact us.

Endpoint map

MethodPathUse it toReturns
POST/v1/quotesGet prices without placing an orderEvery available service, cheapest first, each with a quoteId
POST/v1/ordersPlace an orderTracking number, status, price, delivery deadline
GET/v1/orders/{trackingNumber}Check one orderStatus, current price, times
GET/v1/invoicesList your invoicesInvoice summaries, 25 per page by default
GET/v1/invoices/{invoiceNumber}See one invoiceSummary plus each order's final price

POST/v1/quotes

Prices a shipment. No order is placed.

  • Without service: returns every available service in options[], cheapest first. Services that aren't available are in notAvailable[] with the reason.
  • With service: returns only that service. If it isn't available, you get 422 service_not_available and the message lists the services that are, with prices.
  • In a quote, options[] is the list of services to choose from. It is not the extra charges.
  • Each service in the quote has its own quoteId. It is valid for 30 minutes (expiresAtDisplay).
  • If no service is available, you get 422 service_not_available with the reasons.

Request body: see request fields. Response: see the complete example.

POST/v1/orders

Places an order. Two ways:

SendWhat happensUse when
quoteIdPlaces the order at the quoted price.Recommended. You got a quote and chose a service. Safe to retry (see Retries).
service + full shipmentPrices and places the order in one call. The response has the price.You always use the same service and don't show a price first.

With a quoteId you can send only the quoteId. You can also change contact names, phones, emails, company names, description, reference and purchaseOrder. Addresses, ready time, package and options must match the quote or be left out. If they differ, you get 400 and need a new quote.

Response: trackingNumber, status, service, distanceMiles, price, deliverBy, deliverByDisplay.

GET/v1/orders/{trackingNumber}

Returns one of your orders. The price is current, so charges added later (for example wait time) show here.

Response 200
{
  "trackingNumber": "123456789",
  "status": "in_transit",
  "service": "rush",
  "distanceMiles": 1.2,
  "price": { "base": 40, "options": [], "total": 40, "currency": "USD" },
  "deliverBy": "2026-12-15T11:00:00-08:00",
  "deliverByDisplay": "Tue, Dec 15, 11:00 AM PT",
  "readyTime": "2026-12-15T09:00:00-08:00",
  "readyTimeDisplay": "Tue, Dec 15, 9:00 AM PT",
  "submittedAt": "2026-12-15T08:12:40-08:00",
  "submittedAtDisplay": "Tue, Dec 15, 8:12 AM PT"
}

A tracking number that isn't on your account returns 404 order_not_found.

GET/v1/invoices?offset=0&limit=25

Lists your invoices. limit is 1 to 50 (default 25). offset starts at 0. total is the number of invoices.

Response 200
{
  "invoices": [
    {
      "invoiceNumber": 12345,
      "date": "2026-12-31",
      "dateDisplay": "Thu, Dec 31, 2026",
      "dueDate": "2027-01-30",
      "dueDateDisplay": "Sat, Jan 30, 2027",
      "isPaid": false,
      "totalAmount": 412.5,
      "currency": "USD",
      "orderCount": 6
    }
  ],
  "offset": 0,
  "limit": 25,
  "total": 1
}

GET/v1/invoices/{invoiceNumber}?offset=0&limit=25

One invoice: the summary fields above plus its orders. offset and limit page through the orders.

  • Every order on the invoice is listed, including orders placed by phone, email or our website.
  • placedVia is api for orders placed through this API, other for the rest.
  • quotedTotal and differenceFromQuote are filled in for api orders only, and are null otherwise.
  • Charges added later that have no specific name show as "Additional charge".
Response 200 (other summary fields left out)
{
  "invoiceNumber": 12345,
  "orders": [
    {
      "trackingNumber": "123456789",
      "service": "rush",
      "serviceName": "Courier Rush",
      "reference": "SO-10442",
      "purchaseOrder": "PO-7781",
      "placedVia": "api",
      "price": {
        "base": 40,
        "options": [{ "name": "Additional charge", "amount": 12 }],
        "total": 52,
        "currency": "USD"
      },
      "quotedTotal": 40,
      "differenceFromQuote": 12
    }
  ],
  "ordersOffset": 0,
  "ordersLimit": 25
}

An unknown invoice number returns 404 invoice_not_found.

Requests and responses

Conventions

  • Send Content-Type: application/json on POST requests. Bodies must be under 32 KB.
  • Field names are camelCase and case-sensitive.
  • Unknown fields are rejected with 400 invalid_request. Send only the fields listed here.
  • Responses may gain new fields over time. Ignore fields you don't use.
  • Every response has an X-Request-Id header. Log it. We need it to look up a request.

Request fields (quotes and orders)

Quotes and orders use the same body. On orders, everything except quoteId is optional when you send a quoteId.

FieldTypeRequiredNotes
servicestringNostandard, rush, direct or freight. Required on orders without a quoteId.
pickupobjectYesAddress fields below.
deliveryobjectYesAddress fields below.
readyTimestringYesWhen the package is ready for pickup. Must be in the future. See Times.
packageobjectYesPackage fields below.
optionsstring[]NoExtra services you request. See Options. Up to 20.
descriptionstringNoWhat's in the package. Up to 500 characters.
referencestringNoYour order or job number. Up to 50 characters. Shown on invoices.
purchaseOrderstringNoYour PO number. Up to 50 characters. Shown on invoices.
quoteIdstringOrders onlyThe quoteId of the service you chose from the quote.

Address fields (pickup, delivery)

FieldTypeRequiredNotes
companystringNoUp to 100 characters
contactstringNoPerson the driver asks for. Up to 100 characters.
phonestringNoUp to 30 characters
emailstringNoValid email or empty
address1stringYesStreet address. Up to 100 characters.
address2stringNoSuite, floor, unit
citystringYesUp to 60 characters
statestringYes2-letter code, e.g. WA
postalCodestringYes98101 or 98101-1234
residentialbooleanNoDefault false. true adds the residential charge.

Package fields

FieldTypeRequiredNotes
piecesintegerYes1 to 999
weightLbnumberYesTotal weight of all pieces, in pounds
lengthInnumberYesInches, per piece
widthInnumberYesInches, per piece
heightInnumberYesInches, per piece

Price object

Every price has the same shape:

Price
{
  "base": 40,
  "options": [{ "name": "Residential delivery", "amount": 5 }],
  "total": 45,
  "currency": "USD"
}
  • total is the amount charged. Use it, not the sum of the parts.
  • options[] lists each extra charge. In a quote, any charge not tied to one option shows as "Other charges". Charges added after the order without a specific name show as "Additional charge".

Times

Delivery deadlines and order times come back twice. In a quote, readyTimeDisplay and expiresAtDisplay are display strings only.

FieldExampleUse for
deliverBy2026-12-15T17:00:00-08:00Your system. ISO 8601 with offset.
deliverByDisplayTue, Dec 15, 5:00 PM PTShowing to people. Pacific Time, 12-hour.

readyTime is accepted in either format:

  • ISO 8601 with offset: 2026-12-15T09:00:00-08:00
  • US format, read as Pacific Time: 12/15/2026 9:00 AM

Invoice dates are plain dates (2026-12-31) with a display string (Thu, Dec 31, 2026).

Order status values

StatusMeaning
submittedReceived. No driver assigned yet.
assignedA driver is assigned
in_transitOn the way
in_progressIn progress
deliveredDelivered
cancelledCancelled

Treat any value you don't recognize as in_progress. We may add values.

Errors

Every error has an HTTP status and this body. field is included when one field caused the error.

Error 422
{
  "error": {
    "code": "ready_time_too_late",
    "message": "Standard: ready time is after the 11:00 AM cutoff for this distance. Available services: rush (Courier Rush) $105.00, direct (Courier Direct) $158.50.",
    "field": "readyTime"
  }
}

Branch on code. The message is written for people and may change.

HTTPcodeMeansWhat to do
400invalid_requestA field is missing, malformed or unknown, or an order doesn't match its quoteFix the field named in field. Don't resend unchanged.
401unauthorizedKey missing, wrong or revokedCheck the header. Then contact us.
404order_not_foundNo order with that tracking number on your accountCheck the number.
404invoice_not_foundNo invoice with that number on your accountCheck the number.
404not_foundUnknown pathCheck the URL and /v1 prefix.
405method_not_allowedWrong HTTP methodUse the method in the endpoint map.
409quote_expiredThe quote is over 30 minutes oldGet a new quote. The price may have changed.
422outside_service_areaAn address is outside our area, or the trip is over 44 milesCall us at 425-888-0100 for a manual quote.
422ready_time_too_lateReady time is past this service's cutoffRequest a quote without service to see which services are still available, or choose a later day.
422service_not_availableThe service isn't available for this shipment (weight, size or time)The message lists the available services, with prices. Request a new quote without service.
422address_not_foundWe couldn't locate an address, or there's no driving routeCheck street, city and ZIP.
429rate_limitedOver your request limitWait and retry with backoff.
500internal_errorSomething failed on our sideRetry once. If it repeats, send us the X-Request-Id.
502upstream_unavailableOur system is temporarily unavailableRetry later. On orders, read Retries first.

Services and options

You don't need to know our services to use the API. Request a quote without service and choose from the services that come back. The quote always has the delivery deadline.

ServiceMax weightMax sizeTiming
Standard
standard
200 lb60 in any sideReady by 12:00 PM (under 30 mi) or 11:00 AM (30–44 mi). Delivered by 5:00 PM.
Rush
rush
250 lb60 in any sideDelivered within 2 hours of ready time (under 5 mi), up to 4.5 hours (35–44 mi)
Direct
direct
250 lb60 in any sideDelivered within 1 hour of ready time (under 5 mi), up to 3.5 hours (35–44 mi)
Freight
freight
6,000 lb14 × 8 × 7 ftReady by 1:00 PM (under 25 mi) or 12:00 PM (25–44 mi). Delivered by 5:00 PM.
  • Distance: driving miles, up to 44 for every service.
  • Area: pickup and delivery in King, Pierce or Snohomish county.
  • Freight is offered only for shipments over 250 lb or over 60 in on a side. Those shipments get Freight only.
  • Weight is total weight. Per-piece weight is total ÷ pieces.
  • Dimensional weight = pieces × length × width × height ÷ 139. Prices use the higher of actual and dimensional weight.

Options

Added automatically. Don't send these. Sending one returns 400.

ChargeAdded when
Residential pickup / deliverypickup.residential or delivery.residential is true
WeekendreadyTime is on a Saturday or Sunday
HolidayreadyTime is on a holiday

Request these in options[] when you need them:

SendMeans
call_before_pickupDriver calls the pickup contact before arriving
call_before_deliveryDriver calls the delivery contact before arriving

Each option appears as its own line in price.options[].

Added by the driver after pickup. As with orders placed on our website, these charges are not in the quote. They show in the order's current price and on the invoice:

  • Pieces over 70 lb
  • Any side over 48 in
  • Stairs or limited access at pickup or delivery
  • Pickup or drop-off at an air or marine cargo terminal

Use description to tell us about stairs or a cargo terminal in advance.

Safeguards and limits

SafeguardDetail
Rate limit60 requests per minute and 2,000 per day per key. The daily count resets at midnight UTC (4:00 PM PT, or 5:00 PM PT in summer). Over the limit returns 429. Ask us if you need more.
Request size32 KB maximum body
Strict fieldsUnknown fields are rejected.
Your data onlyA key sees only its own orders and invoices. Anything else returns 404.
Quote expiryA quoteId is valid for 30 minutes
EncryptionHTTPS with TLS 1.2 or newer only
OutagesIf our system is temporarily unavailable you get 502. Requests are not held for later. Retry, or call us at 425-888-0100.

Charges added after an order

The order price matches the quote. As with orders placed on our website, we may add charges after the order is placed (for example wait time). The current price is always on GET /v1/orders/{trackingNumber}, and the final price is on the invoice.

Retries and duplicate orders

If a request fails or times out, use the table below to decide whether to resend it.

Place orders with a quoteId. If you send the same quoteId again, you get back the order already placed. That makes resending safe.

SituationDo this
Timeout or network error on POST /v1/orders with a quoteIdResend the same request. If the first one went through, you get that order back. If it didn't, the order is placed now.
Same, but without a quoteIdDon't retry automatically. Call us at 425-888-0100 to check whether the order went through.
400: "already being placed"Another request for this quote is in progress. Wait a few seconds, then resend.
502 or 400 with "may have been created"Don't retry. Call us at 425-888-0100. We will confirm the order and give you the tracking number.
502 on any other requestRetry with backoff: wait 2, 4, then 8 seconds. Stop after 3 tries.
429Wait at least 60 seconds before retrying.
4xx other than 429Don't retry. Fix the request.

Quotes and GET requests are always safe to retry.

Testing and go-live

  1. Build with your test key

    Use the test URL and your test key while you build. Quotes create nothing on our side. To see the full flow, you can place a test order. One is plenty. It's marked TEST and we cancel it, so no driver is sent and nothing is billed. If anything looks off, we'll call you.

  2. Ask for your production key

    When you're ready, email info@bigfootdelivery.com. We send your production key by secure link. Switch your base URL and key together.

Tips for going live

Support

Technical questions

info@bigfootdelivery.com

425-888-0100

Orders in progress

425-888-0100

info@bigfootdelivery.com

Include:

  • The X-Request-Id from the response
  • The tracking number or quoteId, if any
  • The time of the request (Pacific Time)
  • The error code and message

Never send us your API key. We never ask for it.

Versioning

  • This is version 1. Every path starts with /v1.
  • We may add fields, status values, options and error codes to v1 without notice. Build to ignore what you don't recognize.
  • We won't remove or rename fields in v1. Breaking changes come as a new version, with advance notice by email.
  • Service limits, cutoffs and prices can change. The quote always reflects the current rules.

FAQ

Can I change or cancel an order through the API?

No. Call us at 425-888-0100 with the tracking number.

Why does the invoice price differ from the quote?

A charge was added after the order was placed, such as wait time. differenceFromQuote shows the amount.

Do I need a quote before every order?

No. You can place an order with service and the full shipment. A quote first shows you the price, and makes retries safe.

What about deliveries over 44 miles, multiple stops or recurring routes?

Not available through the API. Call us at 425-888-0100.