Skip to main content
When a nesting job or an export finishes, NestAPI delivers the outcome by making an HTTP POST to a URL you supplied on the request (ResultsWebhookUri for nests, WebHookUri for exports). This is the recommended way to receive results for server-to-server integrations.

Delivery contract

Every webhook, whatever its payload, is delivered the same way:
  • MethodPOST to the URL you supplied.
  • Content typeapplication/json.
  • Body — the JSON document described below, as UTF-8 text. The one exception is the MyNesting endpoint, which delivers an XML document.
  • Enums are numbers. Enum-valued fields arrive as integers, so status and type fields are numeric (e.g. NestingStatus 1, not "Complete"). Two exceptions are called out where they occur: the quote Status is a descriptive string, and the export-failure responseType is the type name.
  • Authentication — there is no signature or Authorization header on the request yet. Secure your endpoint with an unguessable URL and confirm out of band — see Securing your webhook.
  • Delivery — treat it as at-least-once. A job can produce more than one delivery (an interim result followed by a completion), and any delivery can be retried, so make your handler idempotent on RequestId.
The RequestId in every payload is the id you received when you submitted the job, so you can always correlate a delivery back to the request that produced it.

Which payload you receive

The body depends on the endpoint you submitted to. The shapes are not interchangeable — each family has its own field names and its own way of reporting status.

Standard (2D) nesting results

Standard nesting (/v1/nesting, /v1/nesting/geometry, /v1/nesting/parametric) delivers a NestingResultData — a RequestId wrapping a Status (NestingStatusMessage):
This payload is a completion notification and summary — not the full layout. It gives you the per-sheet statistics and, crucially, the ResultIdentity. To get the full report-source result (part placements, renderings) or to produce an export, use that ResultIdentity — see Getting the full result.
Status fields:
The summary fields (efficiency, counts, NestedSheetsInfo, ResultIdentity) are populated for a Result/Complete delivery. On an Error delivery they are absent or empty and ErrorReport / ErrorCode carry the reason instead.
Each NestedSheetsInfo entry describes one sheet layout the nest produced; Multiplicity is how many identical copies of that layout were made: Each UnplacedParts entry is { "PartIdentifier": string, "UnplacedQuantity": number }. Because an interim Result (0) may be delivered before the terminal Complete (1), your handler can receive more than one webhook for the same RequestId. Key your processing on RequestId and treat NestingStatus 1 (or 2) as the final word.

MyNesting XML

/v1/nesting/mynesting is the exception to everything above: it delivers the MyNesting result XML document as the body, not the JSON shape. It exists for compatibility with existing MyNesting integrations; new integrations should use one of the JSON endpoints.

Linear (1D) nesting results

/v1/nesting/1D delivers a Nesting1DWebhookPayload, and unlike the 2D payload it carries the full cutting plan inline in Result:
Top-level fields: The Result is the same Nesting1DResult returned by POST /v1/nesting/1D/result, so a webhook subscriber does not need a follow-up call:

Quote nesting results

The quote endpoints (/v1/nesting/quotenesting, /v1/nesting/geometryquotenesting) report progress as a stream and use a string Status rather than a numeric enum. You can receive three kinds of payload:
One per sub-nest as it completes, so you can show progress:
NestIndex / TotalNests let you show “2 of 5”. Result is a QuoteNestResult:Some numeric fields are also provided unit-neutral (…InUnits), expressed in the request’s ResponseUnits.
Sent once when the whole quote finishes:
The completion carries no result body — collect the full layout with GET /v1/nesting/exportquotenest.

Export deliveries

The export endpoints (/v1/nesting/export, /v1/nesting/exportquotenest) return { "Success": true } on acceptance and deliver the export itself to your WebHookUri later. See export types for how to request one.

Success — one base type, several shapes

Every successful export body is a ResultResponse. That is a base type with subclasses, and the concrete shape depends on the ResponseType you requested. All of them inherit a single ResultIdentity field from the base; each adds its own fields on top:
The JSON carries no type discriminator (no $type field) — it is just the flat set of fields for the concrete subclass. Parse it according to the ResponseType you asked for, not by inspecting the body. ResultIdentity is always present because it is inherited from the base ResultResponse.
Base64EncodedResponse is the DXF, base64-encoded. DXFVersion and ExportFileType are numeric enums.
The rich statistics-and-geometry body. Summary figures at the top, then per-nest and per-part breakdowns:
Runtime returns the same shape (RuntimeResultResponse inherits ReportSourceResponse).
The machine-readable layout: every sheet, the parts placed on it, and any common cuts.

Failure

On failure the body is a small, fixed object — and deliberately carries no internal error detail:
id is the RequestId, resultId the ResultId you asked to export, responseType the type name (a string here, unlike the numeric enums elsewhere), and reference a correlation id you can quote to support to have the underlying failure investigated. Retrying the export is safe.

Getting the full result

The 2D result webhook hands you a summary plus a ResultIdentity. To retrieve the complete report-source result — statistics, per-sheet placements and renderings — call POST /v1/nesting/result/ with the RequestId and that ResultIdentity. It returns a ReportSourceResponseV1, which is the ReportSourceResponse shape above plus a Status (the same NestingStatusMessage the webhook delivered):
This is also how you recover from a missed delivery or independently confirm a webhook is genuine.

Your endpoint’s responsibilities

1

Respond quickly with 2xx

Acknowledge receipt fast. Do heavy processing (rendering, storage, downstream jobs) out of band, after you’ve responded, rather than holding the request open.
2

Be idempotent

Delivery is at-least-once and a single job can produce several deliveries. Key your processing on the RequestId so a repeated or interim delivery is handled safely.
3

Return a stable, reachable URL

The URL must be publicly reachable over HTTPS from NestAPI. For local development, use a tunnelling service.

Securing your webhook

Because your webhook URL receives production data, treat it as a sensitive endpoint. Do not expose it more widely than necessary.
Webhook requests are not signed and carry no Authorization header, so your endpoint cannot yet verify a caller by a shared secret. Until signed webhooks are available:
  • Use HTTPS so the payload is encrypted in transit.
  • Use an unguessable URL — include a long random token in the path or query string and reject any request that doesn’t carry it (e.g. .../hooks/nestapi/9f2c…).
  • Confirm out of band. On receiving a nesting webhook, independently re-fetch the result with its RequestId and ResultIdentity via POST /v1/nesting/result/ using your API key. This confirms the result is genuine before you act on it.
  • Allowlist by source if your infrastructure supports restricting inbound callers.

Retries and missed deliveries

Deliveries can be retried, so design your handler to tolerate duplicates (see idempotency above). If your endpoint is unreachable when a nest completes, you are not left blind — you can always fetch the result on demand with POST /v1/nesting/result/ (see above). Or, for jobs where you’d rather not run a public endpoint at all, use SignalR with delayed start to stream the result over a connection you initiate.

Not receiving webhooks?

  • Confirm ResultsWebhookUri (or WebHookUri for exports) was set on the request and is publicly reachable over HTTPS.
  • Check your endpoint returns 2xx quickly and doesn’t time out.
  • Remember Status is numeric for 2D and 1D nests (e.g. 1, not "Complete") and a string for quote nests — parse accordingly.
  • For exports, parse by the ResponseType you requested — the body has no type field.
  • Fall back to polling POST /v1/nesting/result/ with the RequestId and ResultIdentity.