{"openapi":"3.1.0","info":{"title":"Nextra 360 API","version":"1.1.0","description":"Push catalogs, prices, inventory, ship notices and dealer sales into a Nextra 360 workspace, and pull the orders your dealers place. Every push becomes a batch with an audit trail. Catalog and price batches wait for a person to approve unless the brand's owner turned on automatic apply for clean batches; inventory, ship notices and sales apply immediately."},"servers":[{"url":"https://nextra360.com/api/v1"}],"x-feeds":{"description":"Scheduled feeds (set up in the app) can read your own API. Sign-in styles: none, bearer token, a named header, HTTP Basic, or a URL query parameter. JSON and XML records are found automatically (data, items, results[0].rows, GraphQL edges[].node, repeated XML elements) or at a pinned path. Paging is followed up to 20 pages a run, same site only, 20MB in total: Link rel=next, body next links (next, links.next, paging.next, @odata.nextLink, nextRecordsUrl, _links.next.href), cursors (next_cursor, nextPageToken, page_info, continuation), has_more + starting_after, page/total_pages and offset/limit/total."},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"API key minted in the app (Data page or a brand's page): Authorization: Bearer cfk_..."},"pushToken":{"type":"http","scheme":"bearer","description":"A push URL's token (n360p_...), only for /push."},"stripeSignature":{"type":"apiKey","in":"header","name":"Stripe-Signature","description":"Stripe-signed snapshot event. Verified against the raw request bytes and the deployment webhook signing secret; never a tenant API key."},"ediReceiptSignature":{"type":"apiKey","in":"header","name":"x-nextra-signature","description":"sha256=<hex HMAC-SHA256 of timestamp + '.' + exact raw JSON body using this gateway partner's receiptSecret>. Requires x-nextra-timestamp within 300 seconds."}},"schemas":{"Batch":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"CatalogItem":{"type":"object","description":"One catalog & prices record. Field names are matched loosely (case, spaces, camelCase and common synonyms all work).","properties":{"sku":{"type":"string","description":"SKU (required). Also accepted: sku, item, item no, item number, item code, item #"},"name":{"type":"string","description":"Product name. Also accepted: name, product name, item name, title, description, product description"},"dealerPrice":{"type":["number","string"],"description":"Dealer price. Also accepted: dealer price, dealer, dealer cost, dlr, dlr price, dlr cost. Dollars; name the field ...Cents for integer cents."},"msrp":{"type":["number","string"],"description":"MSRP. Also accepted: msrp, retail, retail price, suggested retail, suggested retail price, list price. Dollars; name the field ...Cents for integer cents."},"category":{"type":"string","description":"Category. Also accepted: category, cat, product category, product type, group, type"},"imageUrl":{"type":"string","description":"Image URL. Also accepted: image, image url, photo, photo url, img, img url"},"collection":{"type":"string","description":"Collection. Also accepted: collection, series, line, family, group name"},"description":{"type":"string","description":"Long description. Also accepted: long description, full description, details, marketing copy, body"},"sellingPoints":{"type":"string","description":"Selling points. Also accepted: selling points, features, key features, highlights, bullets, bullet points"},"lifecycle":{"type":"string","description":"Lifecycle. Also accepted: lifecycle, status, item status, product status, availability status"},"upc":{"type":"string","description":"UPC / GTIN. Also accepted: upc, gtin, ean, barcode, upc code"},"rtoWeekly":{"type":["number","string"],"description":"Rental weekly rate. Also accepted: rto weekly, weekly rate, weekly, rental weekly, rent weekly, weekly rental. Dollars; name the field ...Cents for integer cents."},"rtoTermWeeks":{"type":"integer","description":"Rental term (weeks). Also accepted: rto term, term weeks, rental term, term, weeks"}}},"InventoryPosition":{"type":"object","description":"One inventory record. Field names are matched loosely (case, spaces, camelCase and common synonyms all work).","properties":{"snapshotAt":{"type":["string","null"],"description":"Source inventory as-of time, not upload time. ISO timestamp with timezone, at or before now; a date-only value means midnight UTC. Aliases: asOf, sourceTimestamp. Missing timestamps retain dispatched stock reservations. Only a newer source snapshot received after a shipment can reconcile its reservation; all warehouse positions for that SKU must be newer."},"sku":{"type":"string","description":"SKU (required). Also accepted: sku, item, item no, item number, item code, item #"},"available":{"type":"integer","description":"Available (required). Also accepted: available, qty available, quantity available, avail, atp, available to promise"},"node":{"type":"string","description":"Warehouse. Also accepted: warehouse, node, location, dc, distribution center, whse"},"onHand":{"type":"integer","description":"On hand. Also accepted: on hand, qoh, qty on hand, quantity on hand, onhand"},"allocated":{"type":"integer","description":"Allocated. Also accepted: allocated, committed, reserved, qty allocated, qty committed"},"inbound":{"type":"integer","description":"Inbound. Also accepted: inbound, on order, incoming, qty on order, in transit, po qty"},"nextReceiptDate":{"type":"string","description":"Next receipt date. Also accepted: next receipt, next receipt date, eta, due date, expected date, restock date. YYYY-MM-DD, MM/DD/YYYY or YYYYMMDD."},"transitDays":{"type":"integer","description":"Transit days. Also accepted: transit days, lead time, lead time days, ship days, transit"}}},"ShipmentProgressLine":{"type":"object","required":["proposalLineId","productId","brandId","sku","name","orderedQuantity","cancelledQuantity","activeQuantity","shippedQuantity","deliveredQuantity","remainingQuantity"],"properties":{"proposalLineId":{"type":"string"},"productId":{"type":"string"},"brandId":{"type":"string"},"sku":{"type":"string"},"name":{"type":"string"},"orderedQuantity":{"type":"integer","minimum":0},"cancelledQuantity":{"type":"integer","minimum":0},"activeQuantity":{"type":"integer","minimum":0,"description":"Original ordered units minus permanent remainder cancellations."},"shippedQuantity":{"type":"integer","minimum":0},"deliveredQuantity":{"type":"integer","minimum":0},"remainingQuantity":{"type":"integer","minimum":0,"description":"Active units not yet shipped; cancelled units are excluded."}}},"ShipmentLine":{"type":"object","required":["id","proposalLineId","productId","sku","name","quantity","deliveredQuantity"],"properties":{"id":{"type":"string"},"proposalLineId":{"type":"string"},"productId":{"type":"string"},"sku":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer","minimum":1,"description":"Immutable units dispatched on this consignment."},"deliveredQuantity":{"type":"integer","minimum":0,"description":"Cumulative received units, at most quantity."}}},"Shipment":{"type":"object","description":"One consignment. Its internal id is distinct from the external ASN shipmentId, returned here as shipmentRef.","properties":{"id":{"type":"string"},"orderId":{"type":"string"},"brandId":{"type":["string","null"]},"carrier":{"type":["string","null"]},"trackingNumber":{"type":["string","null"]},"shipmentRef":{"type":["string","null"]},"shippedAt":{"type":"string"},"expectedDeliveryAt":{"type":["string","null"]},"deliveredAt":{"type":["string","null"],"description":"Set only when all units on this consignment are received."},"lines":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentLine"}}}},"Fulfillment":{"type":"object","properties":{"brandId":{"type":"string"},"status":{"type":"string","enum":["open","confirmed","shipped","delivered","cancelled"]},"units":{"type":"integer"},"subtotalCents":{"type":"integer"},"shipment":{"type":["object","null"],"description":"Legacy latest-shipment summary; use shipments for every consignment."},"shipments":{"type":"array","items":{"$ref":"#/components/schemas/Shipment"}},"shipmentProgress":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentProgressLine"}}}},"Order":{"type":"object","description":"Workspace keys receive totalCents, shipments, shipmentProgress and fulfillments. Brand keys receive only their own lines and fulfillment, including its scoped shipment arrays, without order totals or other brands' data.","properties":{"id":{"type":"string"},"status":{"type":"string"},"poNumber":{"type":["string","null"]},"totalCents":{"type":"integer"},"lines":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer"},"unitPriceCents":{"type":"integer"},"lineTotalCents":{"type":"integer"}}}},"shipment":{"type":["object","null"],"description":"Legacy order shipment summary, retained for compatibility."},"shipments":{"type":"array","items":{"$ref":"#/components/schemas/Shipment"}},"shipmentProgress":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentProgressLine"}},"fulfillment":{"$ref":"#/components/schemas/Fulfillment"},"fulfillments":{"type":"array","items":{"$ref":"#/components/schemas/Fulfillment"}},"adjustments":{"$ref":"#/components/schemas/OrderAdjustments"}}},"OrderAdjustmentInput":{"oneOf":[{"type":"object","additionalProperties":false,"required":["operation","reference","reason","lines"],"properties":{"operation":{"const":"request-return"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"type":"boolean"},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}},{"type":"object","additionalProperties":false,"required":["operation","returnId"],"properties":{"operation":{"const":"authorize-return"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"type":"boolean"},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}},{"type":"object","additionalProperties":false,"required":["operation","returnId"],"properties":{"operation":{"const":"reject-return"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"type":"boolean"},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}},{"type":"object","additionalProperties":false,"required":["operation","returnId","reference","lines"],"properties":{"operation":{"const":"receive-return"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"type":"boolean"},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}},{"type":"object","additionalProperties":false,"required":["operation","returnId","reference","lines"],"properties":{"operation":{"const":"issue-credit"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"type":"boolean"},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}},{"type":"object","additionalProperties":false,"required":["operation","creditMemoId","settlementReference","attested"],"properties":{"operation":{"const":"settle-credit"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"const":true,"description":"Explicitly confirms settlement outside Nextra360. This endpoint moves no funds."},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}},{"type":"object","additionalProperties":false,"required":["operation","reference","reason","lines"],"properties":{"operation":{"const":"cancel-remainder"},"brandId":{"type":"string","minLength":1,"maxLength":160,"description":"Required for workspace-key requests/cancellations. A brand key is fixed to its own brand. Return and credit IDs otherwise identify the brand."},"reference":{"type":"string","minLength":1,"maxLength":160,"description":"Stable, unique operation reference. Replay with identical quantities; reusing it with changed quantities fails."},"reason":{"type":"string","minLength":1,"maxLength":1000},"returnId":{"type":"string","minLength":1,"maxLength":160},"creditMemoId":{"type":"string","minLength":1,"maxLength":160},"settlementReference":{"type":"string","minLength":1,"maxLength":160},"attested":{"type":"boolean"},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["lineId","quantity"],"properties":{"lineId":{"type":"string","minLength":1,"maxLength":160,"description":"Proposal-line ID for request-return/cancel-remainder; return-line ID for receive-return/issue-credit."},"quantity":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Units in this operation, not cumulative. Each line ID may appear only once."}}}}}}]},"OrderAdjustments":{"type":["object","null"],"description":"Tenant-scoped return/credit/cancellation history. Brand keys receive only their own records and merchandise totals. Original PO totals remain immutable. No payment balance or refund is implied.","properties":{"progress":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/ShipmentProgressLine"},{"type":"object","properties":{"returnableQuantity":{"type":"integer","minimum":0,"description":"Delivered units not reserved by another non-rejected return."}}}]}},"returns":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"brandId":{"type":"string"},"referenceKey":{"type":"string"},"status":{"enum":["requested","authorized","rejected","received","credited"]},"reason":{"type":"string"},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Use this return-line ID to receive or credit units."},"proposalLineId":{"type":"string"},"productId":{"type":"string"},"sku":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer"},"unitPriceCents":{"type":"integer"},"receivedQuantity":{"type":"integer"},"creditedQuantity":{"type":"integer"}}}},"receipts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"returnLineId":{"type":"string"},"referenceKey":{"type":"string"},"quantity":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}}}}}},"creditMemos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"returnId":{"type":"string"},"referenceKey":{"type":"string"},"status":{"enum":["issued","settled"]},"amountCents":{"type":"integer"},"settlementReference":{"type":["string","null"]},"lines":{"type":"array","items":{"type":"object","properties":{"returnLineId":{"type":"string"},"quantity":{"type":"integer"},"unitPriceCents":{"type":"integer"},"amountCents":{"type":"integer"}}}}}}},"cancellations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"brandId":{"type":"string"},"referenceKey":{"type":"string"},"reason":{"type":"string"},"lines":{"type":"array","items":{"type":"object","properties":{"proposalLineId":{"type":"string"},"productId":{"type":"string"},"quantity":{"type":"integer"}}}}}}},"financials":{"type":"object","properties":{"originalTotalCents":{"type":"integer"},"cancelledTotalCents":{"type":"integer"},"creditedTotalCents":{"type":"integer"},"adjustedTotalCents":{"type":"integer","description":"Merchandise total after cancelled units and issued credits. This is not an outstanding payment balance."}}}}},"TradingPartnerInput":{"type":"object","additionalProperties":false,"required":["brandId","name","gatewayToken","receiptSecret","senderId","receiverId"],"properties":{"brandId":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[A-Za-z0-9_\\-]+$"},"name":{"type":"string","minLength":1,"maxLength":80},"provider":{"type":"string","enum":["gateway","stedi"],"default":"gateway"},"providerConfig":{"type":"object","additionalProperties":false,"required":["partnershipId","transactionSettingId"],"properties":{"partnershipId":{"type":"string","minLength":1,"maxLength":81,"pattern":"^[A-Za-z0-9._-]+$"},"transactionSettingId":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[A-Za-z0-9._-]+$"}}},"gatewayUrl":{"type":"string","maxLength":500,"format":"uri","description":"Gateway provider requires a public HTTPS endpoint with no credentials, query or fragment. Stedi uses the fixed official API endpoint."},"gatewayToken":{"type":"string","minLength":16,"maxLength":4096,"writeOnly":true,"description":"Provider credential, encrypted at rest; never returned."},"receiptSecret":{"type":"string","minLength":32,"maxLength":256,"writeOnly":true,"description":"Gateway callback HMAC secret, encrypted at rest; never returned. Required on create for both providers; Stedi callbacks are not accepted here."},"senderId":{"type":"string","minLength":1,"maxLength":15,"pattern":"^[A-Za-z0-9 _\\-]+$"},"receiverId":{"type":"string","minLength":1,"maxLength":15,"pattern":"^[A-Za-z0-9 _\\-]+$"}},"allOf":[{"if":{"required":["provider"],"properties":{"provider":{"const":"stedi"}}},"then":{"required":["providerConfig"]}}]},"TradingPartnerUpdate":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"testMode":{"type":"boolean","description":"Mode cannot change after any non-cancelled delivery; create a separate production connection."},"gatewayToken":{"type":"string","minLength":16,"maxLength":4096,"writeOnly":true,"description":"Provider credential, encrypted at rest; never returned."},"receiptSecret":{"type":"string","minLength":32,"maxLength":256,"writeOnly":true,"description":"Gateway callback HMAC secret, encrypted at rest; never returned. Required on create for both providers; Stedi callbacks are not accepted here."}}},"TradingPartner":{"type":"object","properties":{"id":{"type":"string"},"brandId":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[A-Za-z0-9_\\-]+$"},"name":{"type":"string","minLength":1,"maxLength":80},"provider":{"type":"string","enum":["gateway","stedi"],"default":"gateway"},"providerConfig":{"type":"object"},"gatewayUrl":{"type":"string","maxLength":500,"format":"uri","description":"Gateway provider requires a public HTTPS endpoint with no credentials, query or fragment. Stedi uses the fixed official API endpoint."},"senderId":{"type":"string","minLength":1,"maxLength":15,"pattern":"^[A-Za-z0-9 _\\-]+$"},"receiverId":{"type":"string","minLength":1,"maxLength":15,"pattern":"^[A-Za-z0-9 _\\-]+$"},"enabled":{"type":"boolean"},"testMode":{"type":"boolean"},"credentialsConfigured":{"type":"boolean","description":"Presence only, not provider authentication or certification."},"createdAt":{"type":"string","format":"date-time"}}},"EdiMessage":{"type":"object","properties":{"id":{"type":"string"},"partnerId":{"type":"string"},"orderId":{"type":"string"},"idempotencyKey":{"type":"string"},"sha256":{"type":"string"},"transactionCode":{"const":"850"},"state":{"enum":["queued","sending","retry","failed","submitted","completed","rejected","cancelled"]},"attempts":{"type":"integer"},"transportStatus":{"enum":["pending","accepted_by_gateway","delivered","failed"]},"functionalStatus":{"enum":["pending","accepted","accepted_with_errors","rejected"]},"businessAcceptance":{"type":"string","description":"Technical receipt never confirms the commercial order."},"gatewayMessageId":{"type":["string","null"]},"lastError":{"type":["string","null"]},"nextAttemptAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"canCancel":{"type":"boolean"},"canRetry":{"type":"boolean"}}},"EdiMessageDetail":{"allOf":[{"$ref":"#/components/schemas/EdiMessage"},{"type":"object","properties":{"payload":{"type":"string"},"originalPayload":{"type":"string"},"receipts":{"type":"array","items":{"type":"object","properties":{"eventId":{"type":"string"},"kind":{"type":"string"},"detail":{"type":"string","description":"JSON-encoded validated receipt evidence; authenticated_import is distinct from provider_poll."},"createdAt":{"type":"string","format":"date-time"}}}}}}]},"EdiReceipt":{"type":"object","additionalProperties":false,"required":["eventId","deliveryId","sha256","gatewayMessageId","kind"],"properties":{"eventId":{"type":"string","minLength":1,"maxLength":120},"deliveryId":{"type":"string"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"Original queued document digest."},"gatewayMessageId":{"type":"string","minLength":1,"maxLength":160},"kind":{"enum":["transport","functional"]},"status":{"enum":["delivered","failed"]},"acknowledgment":{"type":"string","maxLength":524288,"description":"Complete correlated X12 997, required for a functional receipt."}},"oneOf":[{"properties":{"kind":{"const":"transport"}},"required":["status"],"not":{"required":["acknowledgment"]}},{"properties":{"kind":{"const":"functional"}},"required":["acknowledgment"],"not":{"required":["status"]}}]},"ShipNotice":{"type":"object","description":"One ship notices record. Field names are matched loosely (case, spaces, camelCase and common synonyms all work).","properties":{"poNumber":{"type":"string","description":"PO number. Also accepted: po, po number, po #, purchase order, purchase order number, customer po"},"orderId":{"type":"string","description":"Order id. Also accepted: order id, order, order number, order #, sales order"},"shipmentId":{"type":"string","description":"Your stable consignment reference, reused verbatim on retry and delivery notices. A new dispatch requires a new reference. Not the internal id returned in GET shipments."},"carrier":{"type":"string","description":"Carrier. Also accepted: carrier, scac, carrier name, ship via, shipper"},"trackingNumber":{"type":"string","description":"Carrier tracking or PRO number; also serves as the stable reference when shipmentId is omitted."},"shipDate":{"type":"string","description":"Ship date. Also accepted: ship date, shipped, shipped date, date shipped, ship dt. YYYY-MM-DD, MM/DD/YYYY or YYYYMMDD."},"expectedDeliveryDate":{"type":"string","description":"Expected delivery. Also accepted: expected delivery, expected delivery date, delivery date, eta, est delivery, estimated delivery. YYYY-MM-DD, MM/DD/YYYY or YYYYMMDD."},"sku":{"type":"string","description":"SKU. Also accepted: sku, item, item no, item number, item code, item #"},"quantity":{"type":"integer","description":"Quantity shipped. Also accepted: quantity shipped, qty shipped, shipped qty, quantity, qty, units"},"deliveredAt":{"type":"string","description":"Delivery date. For an existing matching consignment, supplied line quantities are cumulative received counts. Omitting lines receives the matching consignment in full."},"delivered":{"type":"string","description":"Delivered (yes/no). Also accepted: delivered, is delivered, delivery confirmed"},"accountNumber":{"type":"string","description":"Dealer account #. Also accepted: account, account number, account #, account no, acct, acct #"},"lines":{"type":"array","minItems":1,"items":{"type":"object","required":["sku","quantity"],"properties":{"sku":{"type":"string"},"quantity":{"type":"integer","minimum":1,"description":"Units dispatched; on a deliveredAt notice matching an existing shipment, cumulative units received. Omit unreceived SKUs instead of sending zero."}}}}}},"SalesPeriod":{"type":"object","description":"One dealer sales (pos) record. Field names are matched loosely (case, spaces, camelCase and common synonyms all work).","properties":{"accountNumber":{"type":"string","description":"Dealer account #. Also accepted: account, account number, account #, account no, acct, acct #"},"dealerName":{"type":"string","description":"Dealer name. Also accepted: dealer, dealer name, customer, customer name, store, store name"},"periodEnd":{"type":"string","description":"Period end (required). Also accepted: period end, week ending, week end, period ending, end date, month ending. YYYY-MM-DD, MM/DD/YYYY or YYYYMMDD."},"periodStart":{"type":"string","description":"Period start. Also accepted: period start, start date, week starting, from. YYYY-MM-DD, MM/DD/YYYY or YYYYMMDD."},"sales":{"type":["number","string"],"description":"Sales amount (required). Also accepted: sales, net sales, gross sales, sales amount, revenue, sales $. Dollars; name the field ...Cents for integer cents."},"units":{"type":"integer","description":"Units. Also accepted: units, units sold, qty sold, quantity sold, pieces"}}}}},"security":[{"bearer":[]}],"paths":{"/ping":{"get":{"summary":"Check a key and see what it can reach","responses":{"200":{"description":"OK"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/ingest":{"post":{"summary":"Send any file as-is (CSV, XLSX, XLS, JSON, XML, or X12 832/846/856)","parameters":[{"name":"brand","in":"query","required":false,"schema":{"type":"string"},"description":"Brand id or exact name. Required for workspace-wide keys on catalog/inventory; brand keys are always filed under their brand."},{"name":"kind","in":"query","schema":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"description":"Omit to auto-detect from the columns (or the X12 transaction set)."},{"name":"format","in":"query","schema":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"description":"Omit to sniff from the bytes."},{"name":"filename","in":"query","schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"text/csv":{"schema":{"type":"string"}},"application/edi-x12":{"schema":{"type":"string"}},"application/xml":{"schema":{"type":"string"}}}},"responses":{"201":{"description":"Applied","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"202":{"description":"Accepted, waiting for review in the app","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"422":{"description":"The payload couldn't be parsed; the batch is recorded as failed with the reason","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/push/{token}":{"post":{"summary":"Push URL: send a payload with no other setup (the token in the path is the credential)","description":"Made on a brand's page or in the brand portal; reaches only that brand and is shown once. Body: raw JSON, CSV, XML, XLSX/XLS or X12 (or multipart with a `file` field), up to 10MB. JSON and XML records are found wherever the payload keeps them (see x-feeds). Every auth failure is the same 401. 60 pushes per minute per URL.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","pattern":"^n360p_"}},{"name":"kind","in":"query","schema":{"type":"string","enum":["catalog","inventory","shipments","sales","auto"]},"description":"Defaults to the push URL's own kind; auto detects it."},{"name":"format","in":"query","schema":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"description":"Omit to sniff from the bytes."},{"name":"records_path","in":"query","schema":{"type":"string"},"description":"Where the records are in a JSON/XML payload, e.g. \"data.items\" or \"results[0].rows\". Detected when omitted."},{"name":"filename","in":"query","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}},"text/csv":{"schema":{"type":"string"}},"application/xml":{"schema":{"type":"string"}},"application/edi-x12":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"202":{"description":"Accepted: applied, or waiting for review (price books unless auto-apply is on)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Unknown, malformed or revoked push URL (always the same answer)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"422":{"description":"The payload couldn't be read; the batch is recorded as failed with the reason","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"429":{"description":"More than 60 pushes a minute on this URL","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/push":{"post":{"summary":"Push URL with the token in a header (Authorization: Bearer n360p_...)","security":[{"pushToken":[]}],"parameters":[{"name":"kind","in":"query","schema":{"type":"string","enum":["catalog","inventory","shipments","sales","auto"]}},{"name":"format","in":"query","schema":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]}},{"name":"records_path","in":"query","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}},"text/csv":{"schema":{"type":"string"}},"application/xml":{"schema":{"type":"string"}},"application/edi-x12":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"202":{"description":"Accepted: applied, or waiting for review (price books unless auto-apply is on)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Unknown, malformed or revoked push URL (always the same answer)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"422":{"description":"The payload couldn't be read; the batch is recorded as failed with the reason","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"429":{"description":"More than 60 pushes a minute on this URL","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/ingest/{id}":{"get":{"summary":"Where a batch stands and what it changed","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"404":{"description":"No such batch in this key's scope"}}}},"/products":{"get":{"summary":"List products (with inventory) in the key's scope","parameters":[{"name":"sku","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"string"}},{"name":"lifecycle","in":"query","schema":{"type":"string","enum":["launch_ready","active","clearance"]}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"post":{"summary":"Create or update catalog items in bulk (up to 10,000)","parameters":[{"name":"brand","in":"query","required":false,"schema":{"type":"string"},"description":"Brand id or exact name. Required for workspace-wide keys on catalog/inventory; brand keys are always filed under their brand."}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/CatalogItem"}},{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CatalogItem"}}}}]}}}},"responses":{"201":{"description":"Applied","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"202":{"description":"Accepted, waiting for review in the app","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"422":{"description":"The payload couldn't be parsed; the batch is recorded as failed with the reason","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/price-book":{"post":{"summary":"Price updates for existing SKUs, in integer cents (legacy shape; same approval policy as /products)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","required":["sku","dealerPrice"],"properties":{"sku":{"type":"string"},"dealerPrice":{"type":"integer","description":"cents"},"msrp":{"type":"integer","description":"cents"}}}}}}}}},"responses":{"200":{"description":"Applied"},"202":{"description":"Held for review"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/inventory":{"get":{"summary":"Inventory positions in the key's scope","responses":{"200":{"description":"OK"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"post":{"summary":"Upsert inventory positions (applied immediately)","description":"Include snapshotAt (aliases asOf/sourceTimestamp) from the source system. Older or equal source snapshots do not overwrite a newer position. Missing timestamps cannot release dispatched reservations. New upload time alone never proves the source has accounted for a shipment.","parameters":[{"name":"brand","in":"query","required":false,"schema":{"type":"string"},"description":"Brand id or exact name. Required for workspace-wide keys on catalog/inventory; brand keys are always filed under their brand."}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InventoryPosition"},{"type":"array","items":{"$ref":"#/components/schemas/InventoryPosition"}},{"type":"object","properties":{"positions":{"type":"array","items":{"$ref":"#/components/schemas/InventoryPosition"}}}}]}}}},"responses":{"200":{"description":"Applied"},"207":{"description":"Some batches held or failed"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/orders":{"get":{"summary":"Store orders in the key's scope","description":"Brand keys: orders with a part for the brand whose store PO is on file, each with only the brand's own lines and fulfillment; no whole-order total. Workspace keys: whole orders with totalCents and one fulfillment per brand. Each fulfillment includes shipments and shipmentProgress (original ordered, cancelled, active, shipped, received and remaining units per proposal line). Workspace orders also include aggregate arrays. Additive adjustments contains returns, receipts, credits, cancellations and merchandise totals within the key's scope. Legacy shipment summaries are preserved. A partially dispatched brand remains confirmed; shipped and delivered require every active, non-cancelled unit. Scope is applied before the limit.","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["staged","awaiting_po","acknowledged","confirmed","shipped","delivered","cancelled"]}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":500}}],"responses":{"200":{"description":"Scoped orders with additive shipment quantities and history","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Order"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/orders/{id}/confirm":{"post":{"summary":"Confirm your part of a store's PO (open -> confirmed), with an optional ship-by date","description":"Needs the store's PO on file. A brand key confirms its own part (a different brandId is 403). A workspace key confirms the named brandId's part, or every brand's part when omitted. Answers with the order as GET /orders shows it.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"shipBy":{"type":"string","format":"date"},"brandId":{"type":"string","description":"Workspace keys only."}}}}}},"responses":{"200":{"description":"Confirmed"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"No such order in this key's scope"},"409":{"description":"Already confirmed, or the store's PO isn't on file"},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/orders/{id}/adjustments":{"post":{"summary":"Request/process returns, issue merchandise credit memos, record external settlement or cancel unshipped quantities","description":"Bearer API keys are tenant-scoped; brand keys are fixed to their own brand, and workspace keys choose a brand for a new return or cancellation. Returns require delivered units, receipts require authorization, and credits cannot exceed returned units not already credited. request-return/cancel-remainder lineId means proposalLineId from shipmentProgress; receive-return/issue-credit lineId means the return line's id from adjustments. Quantities are increments for this uniquely referenced operation. Replaying the same reference and payload is a no-op; conflicting reuse fails. settle-credit requires attested:true and a real external settlementReference; no endpoint transfers funds. Cancellations are permanent and cannot affect dispatched units or an attempted EDI PO. UI roles are separately checked: dealers only request returns, assigned reps process their accounts, managers/admins process tenant orders, and brand users process only their brand.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderAdjustmentInput"}}}},"responses":{"200":{"description":"Applied or replayed; updated order respects the key's scope","content":{"application/json":{"schema":{"type":"object","properties":{"adjustment":{"type":"object","properties":{"id":{"type":"string"},"replayed":{"type":"boolean"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/trading-partners":{"get":{"summary":"List EDI connections in this key's tenant/brand scope","responses":{"200":{"description":"Scoped connections; credentials never returned","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TradingPartner"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"post":{"summary":"Create a disabled EDI partner connection in test mode","description":"Brand keys may create only for their own brand; workspace keys may choose a tenant brand. Stedi requires providerConfig with an existing partnership and transaction setting. Gateway connections require a conforming HTTPS adapter. Setup alone proves neither partner certification nor delivery.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingPartnerInput"}}}},"responses":{"201":{"description":"Disabled test connection created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TradingPartner"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/trading-partners/{id}":{"patch":{"summary":"Enable/disable a scoped connection, select test mode or rotate credentials","description":"No mode change after non-cancelled delivery evidence. Receipt-secret rotation is refused while any delivery is unresolved. Immutable partner identity/endpoint changes require a new connection.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingPartnerUpdate"}}}},"responses":{"200":{"description":"Connection updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TradingPartner"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/edi/messages":{"get":{"summary":"List the latest 100 scoped EDI deliveries, or preview a brand's 850","parameters":[{"name":"previewOrderId","in":"query","schema":{"type":"string"},"description":"With partnerId, returns a preview without queueing or sending."},{"name":"partnerId","in":"query","schema":{"type":"string"},"description":"Required for preview; does not filter the standard message list."}],"responses":{"200":{"description":"Message list or preview","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/EdiMessage"}},{"type":"object","properties":{"payload":{"type":"string"},"testMode":{"type":"boolean"},"notice":{"type":"string"}}}]}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"post":{"summary":"Queue one immutable X12 850 for an enabled scoped partner","description":"Requires an acknowledged/confirmed PO and that brand's open/confirmed fulfillment, with no dispatch. Uses only that brand's active, uncancelled line quantities. A stable idempotencyKey reuses the delivery; another order under the same key fails. A second non-cancelled delivery for the same order/brand is refused. 202 means queued, not delivered or commercially accepted.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["partnerId","orderId","idempotencyKey"],"properties":{"partnerId":{"type":"string"},"orderId":{"type":"string"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":120,"pattern":"^[A-Za-z0-9_.:\\-]+$"}}}}}},"responses":{"202":{"description":"Queued or existing idempotent delivery","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EdiMessage"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/edi/messages/{id}":{"get":{"summary":"Read scoped delivery bytes and receipt evidence","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery and evidence","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EdiMessageDetail"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"post":{"summary":"Cancel a never-attempted delivery, retry a failed submission, or import its correlated X12 997","description":"cancel is allowed only while queued with zero network attempts. retry is for failed, transport-pending submissions below ten attempts. import997 requires a gateway-accepted message and a fully correlated acknowledgment; it records authenticated_import evidence, not provider readback. Technical acknowledgment never confirms the commercial order.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["action"],"properties":{"action":{"enum":["cancel","retry"]}}},{"type":"object","required":["action","acknowledgment"],"properties":{"action":{"const":"import997"},"acknowledgment":{"type":"string","maxLength":524288}}}]}}}},"responses":{"200":{"description":"Updated delivery","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EdiMessageDetail"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Resource not found in this key's tenant and brand scope."},"409":{"description":"State, quantity, idempotency, or reconciliation conflict."},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/edi/receipts/{id}":{"post":{"summary":"Receive a signed generic-gateway transport or 997 receipt","description":"Path id is the partner ID. Only gateway-provider connections accept this callback. Signature is HMAC-SHA256 over timestamp + '.' + exact raw body with receiptSecret; timestamp is Unix seconds within ±300s. Maximum body is 600 KiB. Event ID, document digest and gateway message ID must match an attempted delivery. Duplicate identical receipt is a no-op; conflicting terminal facts fail. No AS2 signature/MDN verification or commercial acceptance is implied.","security":[{"ediReceiptSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"x-nextra-timestamp","in":"header","required":true,"schema":{"type":"string","pattern":"^[0-9]{10}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdiReceipt"}}}},"responses":{"200":{"description":"Receipt recorded or duplicate","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"const":true},"duplicate":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Invalid timestamp or HMAC authentication"},"409":{"description":"Receipt binding, replay or terminal-state conflict"},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/api/billing/webhook":{"servers":[{"url":"https://nextra360.com"}],"post":{"summary":"Receive signed Stripe platform-subscription snapshot events","description":"Server-to-server Stripe integration, outside /api/v1. No bearer API key or browser session is used. Verify Stripe-Signature against exact raw request bytes; maximum body is 1 MiB. Current Stripe customer/subscription state is fetched before transactional reconciliation and persistent event deduplication. Wrong-mode/connected-account events fail. Unknown customers and unrelated event types are acknowledged without creating tenant bindings. Redirects and invoice events never mark manual invoices paid. Disabled integration and retryable failures return 503.","security":[{"stripeSignature":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","type","livemode","data"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"livemode":{"type":"boolean"},"data":{"type":"object","properties":{"object":{"type":"object"}}}}}}}},"responses":{"200":{"description":"Processed, duplicate or ignored event","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"const":true},"duplicate":{"type":"boolean"},"ignored":{"type":"boolean"}}}}}},"400":{"description":"Missing or invalid signature/body"},"413":{"description":"Body exceeds 1 MiB"},"503":{"description":"Billing disabled or reconciliation must be retried by Stripe"}}}},"/orders/{id}/acknowledge":{"post":{"summary":"File the store's PO number (awaiting_po -> acknowledged). Workspace keys only","description":"The PO is the store's commitment to buy, so a brand key gets 403 and confirms with /orders/{id}/confirm instead. The rep and every brand on the order are notified.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["poNumber"],"properties":{"poNumber":{"type":"string"}}}}}},"responses":{"200":{"description":"PO on file"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"409":{"description":"Order isn't awaiting a PO"},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/asn":{"post":{"summary":"Record full or split shipments and receipts (JSON or raw X12 856)","description":"Each notice is matched to exactly one order by orderId, or by poNumber (narrowed by accountNumber). Ambiguous or unmatched notices are reported per notice, never guessed. Nothing ships before the store's PO is on file. Send lines [{sku, quantity}] for a split dispatch and a stable shipmentId (or trackingNumber). The same reference and quantities replay without another dispatch; conflicting quantities are rejected. Use a new reference for the next consignment. Omit lines to ship all remaining quantities. On a deliveredAt notice matching an existing reference, line quantities are cumulative received counts, never increments; omitted SKUs remain unchanged. Omitting receipt lines receives the whole matching consignment. A SKU shipped in several consignments requires a reference to receive a subset unambiguously. All active, non-cancelled units must ship before the brand becomes shipped, and all must be received before delivered. Per-notice skips and conflicts are in result.outcomes; HTTP batch acceptance alone does not mean every notice applied.","parameters":[{"name":"brand","in":"query","required":false,"schema":{"type":"string"},"description":"Brand id or exact name. Required for workspace-wide keys on catalog/inventory; brand keys are always filed under their brand."}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ShipNotice"},{"type":"array","items":{"$ref":"#/components/schemas/ShipNotice"}},{"type":"object","properties":{"shipments":{"type":"array","items":{"$ref":"#/components/schemas/ShipNotice"}}}}]}},"application/edi-x12":{"schema":{"type":"string"}}}},"responses":{"201":{"description":"Applied","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"202":{"description":"Accepted, waiting for review in the app","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"422":{"description":"The payload couldn't be parsed; the batch is recorded as failed with the reason","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/sales":{"post":{"summary":"Dealer sell-through (POS) by period; refreshes each dealer's 12-month sales and trend","parameters":[{"name":"brand","in":"query","required":false,"schema":{"type":"string"},"description":"Brand id or exact name. Required for workspace-wide keys on catalog/inventory; brand keys are always filed under their brand."}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/SalesPeriod"}},{"type":"object","properties":{"sales":{"type":"array","items":{"$ref":"#/components/schemas/SalesPeriod"}}}}]}}}},"responses":{"201":{"description":"Applied","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"202":{"description":"Accepted, waiting for review in the app","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Missing, malformed or revoked key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"403":{"description":"Key is scoped to a different brand, or a brand key tried a workspace-only action","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"422":{"description":"The payload couldn't be parsed; the batch is recorded as failed with the reason","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","example":"job_mu9x..."},"state":{"type":"string","enum":["applied","awaiting_review","rejected","failed"]},"kind":{"type":"string","enum":["catalog","inventory","shipments","sales"]},"source":{"type":"string","enum":["upload","api","feed","portal"]},"format":{"type":"string","enum":["csv","xlsx","xls","json","xml","x12"]},"rows":{"type":"integer"},"autoApplied":{"type":"boolean"},"result":{"type":["object","null"],"description":"What the batch changed (counts, unknown SKUs/dealers, per-notice outcomes)."},"error":{"type":["string","null"]},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"rows":{"type":"array","items":{"type":"integer"}}}}},"statusUrl":{"type":"string"},"reviewUrl":{"type":"string","description":"Where a person sees this batch: the brand portal's batch page for brand keys, the Data page's review screen for workspace keys."}}}}}}}},"429":{"description":"Rate limit (120 requests/min per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/templates/{kind}.csv":{"get":{"summary":"Starter CSV with the canonical columns (no key needed)","security":[],"parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","enum":["catalog","inventory","shipments","sales"]}}],"responses":{"200":{"description":"CSV"}}}}}}