{"ok":true,"data":{"customOrderWrite":{"knife":{"total":72,"current":70,"remaining":2},"status":"custom-order-write-ready","endpoints":{"write":"/api/custom-orders","imCoreWrite":"/api/integrations/im-core/order","legacyBooking":"/api/projects/:projectId/bookings","schema":"/api/orders/schema","adminView":"/api/ops/orders?orderKind=custom_order","ops":"/api/ops/custom-order-write-model","sdkConfig":"/api/sdk/config"},"idempotency":{"requiredFor":["/api/custom-orders","/api/integrations/im-core/order"],"header":"Idempotency-Key","ledgerRows":2,"replayCount":2,"latestWriteAt":"2026-07-08T04:59:24.522Z","retention":"latest 300 write keys in JSON runtime; move to database unique index before high volume"},"requestShape":{"headers":{"Idempotency-Key":"required stable key for POST /api/custom-orders and IM Core bridge writes"},"body":{"orderKind":"custom_order","customCategory":"appointment | consumption | quote_request | voting | internal_request | commercial_candidate | support","projectId":"member project id, slug, or publish hash","itemIds":["price-item-id"],"date":"YYYY-MM-DD","startTime":"HH:mm","source":"im-core | opensdk | official | tenant-page | partner","customer":{"nickname":"display name","phone":"stored only in booking workflow","email":"optional; raw email is redacted from global order rows"},"intakeAnswers":{"field-1":"required goal text","field-2":"optional expected outcome"},"metadata":{"externalOrderRef":"optional alternate idempotency reference"}}},"partnerContract":{"status":"partner-contract-ready","version":"knife-67-partner-contract-auto-deploy","audience":["official-site","opensdk","im-core-mini-app","partner-page","merchant-hash-page"],"canonicalRequest":{"headers":{"Content-Type":"application/json","Idempotency-Key":"merchant-or-client-stable-operation-id"},"body":{"orderKind":"custom_order","customCategory":"appointment | consumption | quote_request | voting | internal_request | commercial_candidate | support","projectId":"matrix-public-appointment","itemIds":["price_product_demo"],"date":"YYYY-MM-DD","startTime":"HH:mm","source":"opensdk","productSurface":"im-mini-app | official-site | partner-page","customer":{"nickname":"display name","phone":"+1 555 0100","email":"customer@example.com"},"intakeAnswers":{"field-1":"Customer goal or request detail","field-2":"Optional expected outcome"},"metadata":{"externalOrderRef":"same value as Idempotency-Key when available"}}},"acceptedInputShapes":[{"id":"canonical-object","status":"recommended","description":"Use nested customer fields and intakeAnswers as a fieldId-to-value object."},{"id":"flat-customer","status":"supported","description":"Top-level nickname, phone, and email remain supported for legacy booking forms."},{"id":"array-intake","status":"supported","description":"intakeAnswers can also be an array of { fieldId, value } records or [fieldId, value] tuples."}],"retryPolicy":{"keyHeader":"Idempotency-Key","sameKeySamePayload":"returns the original booking/customOrder response with idempotency.replayed=true","sameKeyDifferentPayload":"returns 409 idempotency_conflict","missingKey":"POST /api/custom-orders and /api/integrations/im-core/order return 400 missing_idempotency_key","suggestedRetention":"Keep client keys for at least one user retry window; server keeps the latest 300 JSON-runtime keys before database cutover."},"errorMap":[{"code":"missing_idempotency_key","status":400,"action":"Generate a stable operation id and retry with Idempotency-Key."},{"code":"idempotency_conflict","status":409,"action":"Do not retry with the same key; fetch the original order or create a new key for a new intent."},{"code":"missing_intake_field","status":400,"action":"Fetch /api/projects or tenant page data and submit required intakeAnswers by field id."},{"code":"invalid_price_selection","status":400,"action":"Refresh project price items and submit active itemIds."},{"code":"outside_working_day","status":409,"action":"Use /api/projects/:projectId/availability before submitting."}],"deployAutomation":{"mode":"ec2-release-directory","appDir":"/opt/reits-order","sourceSymlink":"/opt/reits-order/source","releaseEnv":"/etc/systemd/system/reits-order.service.d/release.conf","healthCheck":"/api/health","runbook":"deploy/scripts/auto-deploy.sh"},"references":["Stripe idempotent requests: safe retries use a client-provided key and replay the first result.","Shopify idempotent requests: duplicate/conflict prevention for retrying API writes.","Microsoft Bookings: business/service/customer/appointment resources stay explicit.","Google Calendar Events: calendar fulfillment is event-shaped with request/status separation."]},"responseShape":{"customOrder":"public-safe order record with merchant attribution and status URL","booking":"customer booking status payload","idempotency":"key, replayed, replayCount, status, bookingId"},"guardrails":["Keep top-level orderKind fixed to custom_order; use customCategory for business/custom/internal/voting/consumption differences.","Require Idempotency-Key for API and IM Core writes so retry storms do not duplicate orders.","Do not expose raw phone, raw email, private hashes, customer tokens, notes, or intake answers in write-model ops rows.","Do not process payments, card data, trading, settlement, refunds, or finance lifecycle events in this module.","Move the idempotency ledger to a database unique index before high-volume merchant onboarding."]}}}