Overview
External Export Webhooks
Overview
External Export allows you to receive real-time webhook notifications when quotes reach specific states in your workflow. Each time a trigger condition is met, we create a new delivery attempt to your configured webhook endpoint.
Event Flow
-
Enable External Export in Connections and configure your webhook HTTPS URL.
-
Choose triggers: Select one or more:
quote:accepted– Fires when a quote is marked as acceptedquote:won– Fires when a quote is marked as wonmanual– Trigger export on demand via API or UI
-
When a trigger occurs for a quote:
- If this is the first export for the quote, we create a new export job
- If a job already exists for the quote, we add a new attempt to that job
- We immediately dispatch a POST request to your configured webhook URL
-
Request format:
- This describes the request body we POST to your webhook.
- Method:
POST - Headers:
Content-Type: application/json- Authentication header(s) if configured (see Security)
- Body: JSON payload with
schemaVersion: "v1"(see Payload Schema)
-
Response handling:
- We capture your HTTP status code and response body
- Response body is stored as JSON (if non-JSON, wrapped as
{ "raw": "..." }) - Success: HTTP status 2xx (200-299)
- Failed: Any other HTTP status code or network error
-
Job tracking:
- Each quote has one export job that tracks all delivery attempts
- Each trigger event creates a new attempt within that job
- View all attempts and their details in the Export Jobs UI
Triggers
| Trigger | Description |
|---|---|
quote:accepted |
Fires when a quote status changes to "accepted" |
quote:won |
Fires when a quote status changes to "won" |
manual |
Trigger export on demand via API or UI |
Note: Multiple triggers can fire for the same quote over time (e.g., status changes from won → accepted → won). Each trigger creates a new delivery attempt.
Delivery Semantics
Attempts
- Each trigger creates a new attempt: If you change a quote status from "won" to "accepted" to "won" again, three separate webhook deliveries will occur (one per trigger)
- Attempts are tracked: All attempts for a quote are stored under the same export job with incrementing attempt numbers (1, 2, 3, etc.)
- Fresh payload: Each attempt uses the current quote/estimate data at the time of the trigger
Reliability
- Timeout: 30 seconds per HTTP request
- No automatic retries: If a delivery fails, it will NOT be retried automatically
- Manual reprocessing: You can reprocess failed deliveries from the Export Jobs UI or API
- Job reprocessing: When you reprocess a job, it creates a new attempt with the latest quote data
Idempotency
- Job-level: Only one export job exists per quote (reused across all attempts)
- Attempt-level: Each trigger event creates a new attempt with a unique
attempt_number - Recommendation: Your webhook endpoint should be idempotent and handle duplicate deliveries gracefully using the
jobIdand quote identifiers in the payload
Security
Configure authentication in Printhouse Settings under External Export:
| Method | Configuration |
|---|---|
| None | No authentication (not recommended for production) |
| API Key | Custom header name + secret value (e.g., X-API-Key: your-secret) |
| Bearer Token | Authorization: Bearer <token> header |
| Basic Auth | Authorization: Basic <base64(username:password)> header |
Best practices:
- Always use HTTPS URLs
- Rotate credentials regularly
- Validate the X-Printhouse-UID header matches your expected printhouse
- Implement signature verification if needed (contact support for webhook signing)
Payload Schema
See the full schema pages: - Response – EstimateExportResponse - Components - Example payload
Includes: - Job and quote identifiers - Estimate details with pricing - Product structure with attributes and production steps - Customer and delivery information - Metadata and timestamps
Schema version: v1 (indicated by schemaVersion field in payload)
Monitoring & Troubleshooting
View Export Jobs
- Navigate to Export Jobs in your dashboard
- Filter by status, date range, or quote ID
- View all attempts for each job with request/response details
Reprocess Failed Deliveries
- Find the failed job in Export Jobs list
- Click Reprocess to create a new attempt
- New attempt uses the latest quote data
- View the new attempt result in the job details
Common Issues
| Issue | Solution |
|---|---|
| Job not created when status changes | Check that you have an External connection configured with the correct trigger (quote:won or quote:accepted) enabled |
| Webhook not receiving data | Verify webhook URL is accessible via HTTPS and returns 2xx status |
| Timeout errors | Ensure your endpoint responds within 30 seconds |
| Authentication failures | Verify credentials are correct in Printhouse Settings |
Example Workflow
Scenario: A quote goes through your typical workflow
-
Day 1: Quote created, status is "pending"
- No export triggered
-
Day 2: Quote status changed to "won"
- ✅ Export job created (Job ID:
abc-123) - ✅ Attempt #1 dispatched to your webhook
- ✅ Your endpoint returns 200 OK
- ✅ Job marked as "success"
- ✅ Export job created (Job ID:
-
Day 3: Customer changes their mind, status changed to "accepted"
- ✅ Same job reused (Job ID:
abc-123) - ✅ Attempt #2 dispatched with updated quote data
- ❌ Your endpoint returns 500 error
- ❌ Job marked as "failed"
- ✅ Same job reused (Job ID:
-
Day 3 (later): You fix your endpoint and click "Reprocess" in UI
- ✅ Same job reused (Job ID:
abc-123) - ✅ Attempt #3 dispatched with latest quote data
- ✅ Your endpoint returns 200 OK
- ✅ Job marked as "success"
- ✅ Same job reused (Job ID:
Result: One export job with three attempts tracked in your dashboard