Docs menutap to expand

Developer

API examples

curl examples for Wave's HTTP API: check the connection, read the guide, find a job, catch up on changes, open a job, add a note, build an estimate, record drying readings, work with photos and documents, and download a PDF.

Last updated

An AI assistant connects to Wave over MCP at https://wave-mcp.prod.buildwithwave.com/mcp. Scripts and integrations call the same tools over HTTP at https://api.go.buildwithwave.com/api/v1, with the same key and the same Authorization: Bearer header. Both are covered in Where to send the key.

These examples keep the address and the key in two shell variables. WAVE_KEY holds a stand-in key, so swap in your own.

WAVE_API="https://api.go.buildwithwave.com/api/v1"
WAVE_KEY="wave_live_EXAMPLE_NOT_A_REAL_KEY"

Check the connection

GET /api/v1/context returns the person the key works for, the company, its timezone, whether Slack is connected, whether the key is read or write, and the company's credits.

curl "$WAVE_API/context" \
  -H "Authorization: Bearer $WAVE_KEY"

Read the guide

GET /api/v1/guide returns how Wave names jobs, dates, and amounts, every tool with what it does, and recipes for common asks. It is the same guide an assistant reads with get_guide.

curl "$WAVE_API/guide" \
  -H "Authorization: Bearer $WAVE_KEY"

Find a job

GET /api/v1/jobs takes q (a customer, street, title, job number, claim number, carrier, adjuster, or phone), status, drying, photos (with or without), created_from, created_to, limit, and cursor. A match includes id, job_number, title, customer_name, address, status, and photo_count.

curl "$WAVE_API/jobs?q=Elm%20Street&limit=5" \
  -H "Authorization: Bearer $WAVE_KEY"
curl "$WAVE_API/jobs?drying=active" \
  -H "Authorization: Bearer $WAVE_KEY"

Open one job with GET /api/v1/jobs/job_id, by its id or its number, such as 16. Look up a person with GET /api/v1/customers?q=Hernandez. Search Wave's catalog with GET /api/v1/price-list?q=drywall.

curl "$WAVE_API/jobs/16" \
  -H "Authorization: Bearer $WAVE_KEY"

Catch up on changes

GET /api/v1/changes lists what changed across the company's jobs, oldest first: notes, status moves, assignments, files added, and schedule and estimate activity. Send the reply's next_cursor back as cursor next time to get only newer changes. kind narrows the list to notes, visits, files, schedule, changes, or estimates.

curl "$WAVE_API/changes?kind=notes" \
  -H "Authorization: Bearer $WAVE_KEY"

Create a job

POST /api/v1/jobs creates the job and fills it in with one request. Only operation_id is required. Send whatever you have. This one opens a roof claim.

curl "$WAVE_API/jobs" \
  -H "Authorization: Bearer $WAVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operation_id":"job-alder-001","customer_name":"Maria Hernandez","customer_phone":"555-0142","customer_email":"maria@example.com","address_line1":"412 Alder Street","city":"Springfield","region":"OR","postal_code":"97477","loss_type":"storm","carrier":"Northline Mutual","claim_number":"88-1234","policy_number":"HO-55120","assignee":"Luis"}'

Add a note

POST /api/v1/jobs/job_id/notes takes operation_id and text. The note posts as the person who owns the key. It also goes to Slack when an admin has turned on New note in Slack notifications, a switch that starts off.

curl "$WAVE_API/jobs/16/notes" \
  -H "Authorization: Bearer $WAVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operation_id":"note-alder-001","text":"Adjuster inspected the roof and asked for photos of the south slope."}'

Create an estimate

POST /api/v1/jobs/job_id/estimates takes operation_id, and can include scope_summary, rooms, and line_items. A catalog line sends code with quantity, or units_per_day for items billed by the day, and Wave sets the price. Your own line sends description, unit, quantity, and unit_price. The reply includes credits, the credits it used. This one is a kitchen fire.

curl "$WAVE_API/jobs/21/estimates" \
  -H "Authorization: Bearer $WAVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operation_id":"est-birch-001","scope_summary":"Kitchen fire, smoke and soot","rooms":[{"name":"Kitchen","length":12,"width":14,"height":8}],"line_items":[{"code":"SEAL-WALL","quantity":416,"room_id":"Kitchen"},{"description":"Electrician invoice, range circuit repair","unit":"EA","quantity":1,"unit_price":450,"room_id":"Kitchen"}]}'

SEAL-WALL is a stand-in. Search GET /api/v1/price-list and send a code from the results. Add more lines later with POST /api/v1/estimates/estimate_id/line-items.

Record drying readings

POST /api/v1/jobs/job_id/drying-log/readings takes operation_id, source_of_values (dictated_by_user or read_from_log), and a day, an area, and readings. Send rows to record several days or areas at once. Wave starts the log and adds the area when it needs to.

curl "$WAVE_API/jobs/12/drying-log/readings" \
  -H "Authorization: Bearer $WAVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operation_id":"dry-elm-day2","source_of_values":"dictated_by_user","day":2,"area":"Kitchen","readings":[{"metric":"temp_f","value":72},{"metric":"rh_pct","value":45},{"metric":"drywall","value":18}]}'

Photos and documents

GET /api/v1/jobs/job_id/photos lists a job's photos with their rooms and captions, and room narrows it to one room or Unsorted. POST /api/v1/jobs/job_id/photos/rooms files photos into rooms, and PATCH /api/v1/jobs/job_id/photos writes captions. To add photos from a script, send them to POST /api/v1/jobs/job_id/photos as a multipart upload: a part named photo for each photo, and a part named meta with JSON that holds the operation_id and, when you want one, the room. See upload_job_photos.

curl "$WAVE_API/jobs/16/photos?room=Unsorted" \
  -H "Authorization: Bearer $WAVE_KEY"

GET /api/v1/jobs/job_id/documents lists the files on a job's Files tab, and GET /api/v1/documents/document_id reads a PDF from that list, page by page.

curl "$WAVE_API/jobs/21/documents" \
  -H "Authorization: Bearer $WAVE_KEY"

Download a PDF

GET /api/v1/jobs/job_id/export-pdf takes documents, what the PDF holds, such as estimate, drying_log, or photos. Repeat it to build one packet. The reply carries url, a page whose Download button builds the PDF the Export dialog builds. Opening the page changes nothing. Downloading a PDF that holds the estimate marks the estimate final in Wave.

curl "$WAVE_API/jobs/21/export-pdf?documents=estimate&documents=photos" \
  -H "Authorization: Bearer $WAVE_KEY"

GET /api/v1/jobs/job_id/photos/export returns a link to a ZIP of the job's photos, or of one room's with room.

Retry a write

Send the same operation_id with the same details, and Wave returns the first result without saving twice. A new action uses a new operation_id. If that id was already used with different details, Wave says so, and you resend the original request unchanged or start the new one with a new id.