{"openapi":"3.1.0","info":{"title":"WireHQ API","version":"1.0.0","description":"Field management for electrical contractors, by Heron Networks LLC. The same jobs the WireHQ web app runs: jobs with live profitability, customers, estimates and invoices, and field entries (clock in/out, material pulls) recorded offline and sent later without double counting. Authenticate with a per-user API key from Settings > Agent access (Authorization: Bearer wh_sk_...). A key acts as the user who created it, inside that user's company and plan; read keys cannot write. Money amounts are integer cents. No endpoint here takes, moves or refunds money, changes the subscription, or deletes the account. Rate limit: 120 calls per minute per key. MCP server: POST https://prewire.tech/mcp. CLI: npx wirehq-cli.","contact":{"name":"WireHQ support","email":"support@prewire.tech","url":"https://prewire.tech/docs/agents"}},"servers":[{"url":"https://prewire.tech"}],"paths":{"/api/v1/me":{"get":{"summary":"Who am I","description":"The user, company, key and subscription status this key acts as. Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/jobs":{"get":{"summary":"List jobs","description":"Jobs, newest activity first (up to 500). Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["estimate","approved","active","awaiting_inspection","inspection_failed","complete","invoiced","paid","lost","cancelled"]}}]},"post":{"summary":"Create a job","description":"Create a job for an existing customer; starts in status estimate. Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["customer_id","title","site_address"],"properties":{"customer_id":{"type":"string"},"title":{"type":"string"},"site_address":{"type":"string"},"description":{"type":"string"},"est_labor_cents":{"type":"integer","minimum":0},"est_material_cents":{"type":"integer","minimum":0},"contract_total_cents":{"type":"integer","minimum":0},"scheduled_start_ms":{"type":"integer"},"scheduled_end_ms":{"type":"integer"}}}}}}}},"/api/v1/jobs/{id}":{"get":{"summary":"Get a job","description":"One job plus live profitability (estimated vs actual labor/materials, margin %). Costs are internal to the shop. Requires a read-scope key. The profitability block carries the after-overhead answer: verdict (green/red), breakeven_hours, hours_left, overhead_per_hour_cents, projected_profit_cents; overhead_set false means those figures exclude overhead.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/v1/jobs/{id}/status":{"post":{"summary":"Move a job to a new status","description":"Follows the WireHQ job state machine; the server refuses other moves. lost, cancelled and invoiced require \"confirm\": true (otherwise 409 with what would happen). Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"description":"Confirmation required: nothing was changed. The body says what WOULD happen; repeat with \"confirm\": true.","content":{"application/json":{"schema":{"type":"object","properties":{"confirmation_required":{"type":"boolean"},"message":{"type":"string"}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["approved","active","awaiting_inspection","inspection_failed","complete","invoiced","lost","cancelled"]},"confirm":{"type":"boolean"}}}}}}}},"/api/v1/jobs/{id}/estimates":{"post":{"summary":"Create an estimate","description":"Draft estimate from line items; returns the customer approval link. Sends nothing. Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lines"],"properties":{"title":{"type":"string"},"notes":{"type":"string"},"lines":{"type":"array","minItems":1,"items":{"type":"object","required":["description","qty","unit_price_cents"],"properties":{"description":{"type":"string"},"qty":{"type":"number","exclusiveMinimum":0},"unit_price_cents":{"type":"integer","minimum":0},"type":{"type":"string","enum":["labor","material"]}}}}}}}}}}},"/api/v1/customers":{"get":{"summary":"List customers","description":"Customers, alphabetical (up to 500). Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"summary":"Create a customer","description":"Add a customer. Does not contact them. Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"billing_address":{"type":"string"},"notes":{"type":"string"}}}}}}}},"/api/v1/invoices":{"get":{"summary":"List invoices","description":"Invoices, newest first. Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["locked","draft","sent","paid","overdue","void"]}},{"name":"job_id","in":"query","schema":{"type":"string"}}]},"post":{"summary":"Create a draft invoice","description":"Draft invoice on a job; not visible to the customer until sent. Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["job_id","amount_cents"],"properties":{"job_id":{"type":"string"},"amount_cents":{"type":"integer","minimum":1},"due_date_ms":{"type":"integer"},"notes":{"type":"string"}}}}}}}},"/api/v1/invoices/{id}/send":{"post":{"summary":"Send an invoice","description":"Marks a draft invoice sent so the customer can pay it from their portal page. Requires \"confirm\": true (otherwise 409 with what would be sent). Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"description":"Confirmation required: nothing was changed. The body says what WOULD happen; repeat with \"confirm\": true.","content":{"application/json":{"schema":{"type":"object","properties":{"confirmation_required":{"type":"boolean"},"message":{"type":"string"}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"boolean"}}}}}}}},"/api/v1/estimates":{"get":{"summary":"List estimates","description":"Estimates across this company's jobs. Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/search":{"get":{"summary":"Search","description":"Text search across jobs, customers and invoices; returns {results:[{id,title,url}]}. Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}}]}},"/api/v1/overhead":{"get":{"summary":"Get the shop's overhead","description":"Monthly overhead (cents) and crew hours billed a month; null = not entered, and job P&L figures then exclude overhead. Requires a read-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"summary":"Set the shop's overhead","description":"Set the monthly overhead (whole cents) and crew hours billed a month; every job's P&L then says how many crew hours it has left before it stops making money after overhead. Both null clears. Owner or office role. Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["overhead_monthly_cents","overhead_hours_monthly"],"properties":{"overhead_monthly_cents":{"type":["integer","null"],"minimum":0,"maximum":1000000000},"overhead_hours_monthly":{"type":["integer","null"],"minimum":1,"maximum":100000}}}}}}}},"/api/v1/field/entries":{"post":{"summary":"Record field entries (clock in/out, material pulls)","description":"Send clock-ins, clock-outs and material pulls made on a job site, in the order they happened (at most 50). You choose each entry's id and keep it: a resend is reported as replayed and never counted twice. Each result is applied, replayed, conflict or rejected, with a reason and a sentence. Returns each touched job's live P&L. Requires a write-scope key.","security":[{"apiKey":[]}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entries"],"properties":{"entries":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","required":["id","kind","at_ms"],"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,64}$","description":"Your id; a clock_out uses its clock_in id"},"kind":{"type":"string","enum":["clock_in","clock_out","material"]},"job_id":{"type":"string"},"item_id":{"type":"string","description":"Price book item id (material)"},"qty":{"type":"number","exclusiveMinimum":0,"maximum":10000},"at_ms":{"type":"integer"},"labor_type":{"type":"string","enum":["st","ot","dt"]}}}}}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"A WireHQ API key (wh_sk_...) from Settings > Agent access."}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"Unauthorized":{"description":"Missing, unknown or revoked key","headers":{"WWW-Authenticate":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"SubscriptionRequired":{"description":"The company's trial ended or its subscription is not active; an owner can subscribe at https://prewire.tech/settings/billing","content":{"application/json":{"schema":{"type":"object"}}}},"RateLimited":{"description":"More than 120 calls in a minute for this key","headers":{"Retry-After":{"schema":{"type":"integer"}}}}}}}