01
Scheduled feed
Point us at a URL: a file, or your own API (JSON or XML, paged, behind a key). We test it, show what we found, and fetch it hourly, daily or weekly.
02
API push
POST files or JSON from your ERP, PIM or an iPaaS step (Zapier, Make, Celigo). A push URL needs no setup at all; a key opens every endpoint.
03
Upload
Drag a price book, stock report or EDI file onto the Data page. Columns are matched for you.
Authentication
Ask the workspace manager for a key (Data page, or the brand's own page for a key limited to one brand). Send it on every request:
Authorization: Bearer cfk_...
curl https://nextra360.com/api/v1/ping -H "Authorization: Bearer $NEXTRA360_KEY"120 requests per minute per key. Keys are stored hashed and can be revoked at any time.
The fastest path: send the file you already have
curl -X POST "https://nextra360.com/api/v1/ingest?brand=<brand id or name>" \
-H "Authorization: Bearer $NEXTRA360_KEY" \
-F file=@pricebook.xlsxThe answer is a batch: 201 applied, 202 waiting for review in the app, 422 unreadable (with the reason). Brand keys don't need ?brand.
What applies when
- Catalog and price batches wait for a manager to approve, unless the brand has automatic apply on and the batch has no warnings (an 18%+ price drop, unreadable rows, duplicate or unknown SKUs).
- Inventory, ship notices and dealer sales from the API or a feed apply as they arrive; rows that can't be read are skipped and reported.
- Files a manager uploads on the Data page always wait for review. Files a brand uploads in its own portal follow the same rules as its API pushes.
- Ship notices never ship an order whose store PO isn't on file, and a PO number that matches more than one order is reported, never guessed.
- Catalog and sales updates replace the matching record. Inventory with a known source timestamp accepts only newer snapshots. Replaying a shipment reference preserves its original dispatched quantities. A feed that returns identical bytes is skipped.
Endpoints
| GET | /api/v1/ping | Check a key and see what it can reach. |
| POST | /api/v1/ingest | Send any file as-is: CSV, Excel, JSON, XML, or EDI X12 832 / 846 / 856. The kind is detected from the columns. |
| POST | /api/v1/push/{token} | A push URL: POST JSON, CSV, XML, Excel or X12 to it with no other setup. Filed under the brand it was made for. ?kind= to override its kind, ?kind=auto to detect. |
| POST | /api/v1/push | The same push URL with the token in Authorization: Bearer n360p_... instead of the path. |
| GET | /api/v1/ingest/{id} | Where a batch stands (applied, awaiting review, failed) and what it changed. |
| POST | /api/v1/products | Create or update catalog items in bulk, JSON. Prices in dollars. |
| GET | /api/v1/products | List products with inventory, filtered by sku, category or lifecycle. |
| POST | /api/v1/inventory | Upsert inventory positions by SKU and warehouse. Include snapshotAt from the source system to reconcile dispatched stock reservations. |
| GET | /api/v1/orders | Store POs to act on. A brand key sees the orders carrying its line once the store's PO is on file, with only its own lines and its own fulfillment (status, ship-by, tracking). A workspace key sees whole orders with one fulfillment per brand. Each fulfillment includes every shipment and per-line shipped, received and remaining quantities. |
| POST | /api/v1/orders/{id}/confirm | Confirm your part of a store's PO, optionally with {"shipBy":"YYYY-MM-DD"}. Brand keys confirm their own part; workspace keys name a brandId or confirm every brand. |
| POST | /api/v1/orders/{id}/acknowledge | Workspace keys only: file the store's PO number on an order waiting for one. A brand key gets 403; brands confirm instead. |
| POST | /api/v1/orders/{id}/adjustments | Returns, receipt of returned units, merchandise credit memos, external settlement records and cancellation of unshipped quantities. Brand keys remain fixed to their brand. |
| GET / POST | /api/v1/trading-partners | Read or create scoped EDI connections. New connections start disabled and in test mode. |
| PATCH | /api/v1/trading-partners/{id} | Enable a connection, select test mode or rotate credentials. Existing delivery evidence keeps its original mode. |
| GET / POST | /api/v1/edi/messages | Read recent delivery states, preview an 850, or queue one immutable brand purchase order. |
| GET / POST | /api/v1/edi/messages/{id} | Read delivery evidence, cancel a never-attempted message, retry a failed submission or import a correlated 997. |
| POST | /api/v1/edi/receipts/{id} | Generic-gateway callback using a partner HMAC signature and timestamp. The id is the partner ID; tenant API keys do not authenticate this callback. |
| POST | /api/v1/asn | Full or split shipments, JSON or raw X12 856. Match by order id or PO, use a stable shipmentId and per-SKU quantities, then send cumulative received quantities with deliveredAt. |
| POST | /api/v1/sales | Dealer sell-through (POS) by period. Refreshes each dealer's 12-month sales and trend. |
| POST | /api/v1/price-book | Legacy: price updates for existing SKUs in integer cents. |
Fields
Column and JSON field names are matched loosely: case, spacing, camelCase and the synonyms below all work. Prices are dollars unless the field name ends in "Cents". Templates: catalog.csv, inventory.csv, shipments.csv, sales.csv.
Catalog & prices
| sku * | SKU. Also: sku, item, item no, item number, item code, item #, model, model no |
| name | Product name. Also: name, product name, item name, title, description, product description, item description, short description |
| dealerPrice | Dealer price. Also: dealer price, dealer, dealer cost, dlr, dlr price, dlr cost, wholesale, wholesale price |
| msrp | MSRP. Also: msrp, retail, retail price, suggested retail, suggested retail price, list price, list, srp |
| category | Category. Also: category, cat, product category, product type, group, type, dept, department |
| imageUrl | Image URL. Also: image, image url, photo, photo url, img, img url, picture, picture url |
| collection | Collection. Also: collection, series, line, family, group name |
| description | Long description. Also: long description, full description, details, marketing copy, body |
| sellingPoints | Selling points. Also: selling points, features, key features, highlights, bullets, bullet points, benefits, claims |
| lifecycle | Lifecycle. Also: lifecycle, status, item status, product status, availability status |
| upc | UPC / GTIN. Also: upc, gtin, ean, barcode, upc code |
| rtoWeekly | Rental weekly rate. Also: rto weekly, weekly rate, weekly, rental weekly, rent weekly, weekly rental, rto weekly cents |
| rtoTermWeeks | Rental term (weeks). Also: rto term, term weeks, rental term, term, weeks |
Inventory
| snapshotAt | Inventory as-of time (UTC). Also: snapshot at, snapshot time, as of, as of time, inventory timestamp, source timestamp |
| sku * | SKU. Also: sku, item, item no, item number, item code, item #, model, model no |
| available * | Available. Also: available, qty available, quantity available, avail, atp, available to promise, free stock, qty |
| node | Warehouse. Also: warehouse, node, location, dc, distribution center, whse, facility, ship from |
| onHand | On hand. Also: on hand, qoh, qty on hand, quantity on hand, onhand |
| allocated | Allocated. Also: allocated, committed, reserved, qty allocated, qty committed |
| inbound | Inbound. Also: inbound, on order, incoming, qty on order, in transit, po qty |
| nextReceiptDate | Next receipt date. Also: next receipt, next receipt date, eta, due date, expected date, restock date, arrival date, next available |
| transitDays | Transit days. Also: transit days, lead time, lead time days, ship days, transit |
Ship notices
| poNumber | PO number. Also: po, po number, po #, purchase order, purchase order number, customer po, po no |
| orderId | Order id. Also: order id, order, order number, order #, sales order |
| shipmentId | Shipment id. Also: shipment, shipment id, shipment number, asn, asn number, bol, bill of lading, manifest |
| carrier | Carrier. Also: carrier, scac, carrier name, ship via, shipper |
| trackingNumber | Tracking number. Also: tracking, tracking number, tracking #, tracking no, pro, pro number |
| shipDate | Ship date. Also: ship date, shipped, shipped date, date shipped, ship dt |
| expectedDeliveryDate | Expected delivery. Also: expected delivery, expected delivery date, delivery date, eta, est delivery, estimated delivery |
| sku | SKU. Also: sku, item, item no, item number, item code, item #, model, model no |
| quantity | Quantity shipped. Also: quantity shipped, qty shipped, shipped qty, quantity, qty, units |
| deliveredAt | Delivered date. Also: delivered at, delivered date, date delivered, delivered on, pod date, actual delivery, actual delivery date |
| delivered | Delivered (yes/no). Also: delivered, is delivered, delivery confirmed |
| accountNumber | Dealer account #. Also: account, account number, account #, account no, acct, acct #, customer number, customer # |
Dealer sales (POS)
| accountNumber | Dealer account #. Also: account, account number, account #, account no, acct, acct #, customer number, customer # |
| dealerName | Dealer name. Also: dealer, dealer name, customer, customer name, store, store name, retailer, account name |
| periodEnd * | Period end. Also: period end, week ending, week end, period ending, end date, month ending, date, as of |
| periodStart | Period start. Also: period start, start date, week starting, from |
| sales * | Sales amount. Also: sales, net sales, gross sales, sales amount, revenue, sales $, amount, total sales |
| units | Units. Also: units, units sold, qty sold, quantity sold, pieces |
Ship notices need a PO number or an order id; a dealer account number narrows a PO two stores share. Dealer sales need the dealer's account number (set on its account page) or its exact name. Inventory needs available or on-hand quantity.
Split shipments and receipts
Send the units leaving on each truck. Give every consignment a stable shipmentId, or use its tracking number. Retry with the same reference and quantities; a retry does not dispatch more units. Use a new reference for the next shipment. Reusing a reference with different shipped quantities is rejected. Omitting lines ships all remaining units in the key's scope.
{
"orderId": "ord_example",
"shipmentId": "ACME-LOAD-001",
"carrier": "Estes",
"trackingNumber": "PRO-12345",
"shipDate": "2026-10-10",
"lines": [
{
"sku": "ACME-SOFA-01",
"quantity": 2
}
]
}Post this JSON to /api/v1/asn. Later, send the same reference with deliveredAt and the total received so far. Receiving one of those two sofas looks like this. Repeating it still means one received, not two. Omit unreceived SKUs; supplied API quantities must be positive whole numbers. Omit lines to receive the matching shipment in full.
{
"orderId": "ord_example",
"shipmentId": "ACME-LOAD-001",
"deliveredAt": "2026-10-12",
"lines": [
{
"sku": "ACME-SOFA-01",
"quantity": 1
}
]
}Read GET /api/v1/orders for each fulfillment's shipments and shipmentProgress. Shipment lines carry dispatched quantity and cumulative deliveredQuantity; progress reports ordered, shipped, received and remaining units. Brand keys see only their own lines and consignments. Workspace keys also receive order-wide arrays. The older shipment summary stays available. The returned internal shipment id is distinct from your external reference, which appears as shipmentRef.
A partially shipped brand remains confirmed. It becomes shipped only when all active units leave, and delivered only when all arrive. Permanently cancelled units are excluded from those remaining commitments. If the same SKU travels in multiple consignments, include the shipment reference on its receipt. Check the batch's result.outcomes for skipped or conflicting notices; a successful batch response does not mean every notice changed an order.
Returns, credits and order changes
Use POST /api/v1/orders/{id}/adjustments for the operations below. Read the scoped adjustments object in GET /api/v1/orders for return IDs, receipt history, credit memos and adjusted merchandise totals. Brand keys can act only on their own brand. Workspace keys select a brand for new returns and cancellations.
request-return: use a stable reference, reason and proposal-line IDs from shipment progress. Request only delivered units not already assigned to another return.authorize-returnorreject-return: identify the pending return by its return ID.receive-return: identify the return and its return-line IDs, with a unique receipt reference and quantities received now.issue-credit: identify received return-line quantities not already credited. Amounts use original sale prices.settle-credit: supply the credit memo ID, an external settlement reference andattested: true. This records a settlement made outside Nextra360; it does not send money or issue a card refund.cancel-remainder: permanently cancel only unshipped proposal-line quantities. Original PO lines and shipment history stay intact. Attempted EDI purchase orders require partner reconciliation before amendment.
{
"operation": "request-return",
"brandId": "brd_example",
"reference": "RMA-2026-001",
"reason": "Damaged upholstery",
"lines": [
{
"lineId": "pline_example",
"quantity": 1
}
]
}Adjustment quantities are increments for that referenced operation. Retry the same reference and payload to avoid counting twice. A conflicting reference, excess quantity or invalid state returns 409. Returned merchandise is not automatically added to available stock; a reconciled inventory feed supplies that evidence.
Inventory source time
Include snapshotAt with inventory positions: the time your warehouse system measured the stock, with a timezone, at or before now. asOf and sourceTimestamp are accepted aliases. For example: 2026-10-10T14:30:00Z. A date without a time means midnight UTC.
Shipment reservations remain in place until every warehouse position for that SKU has a source snapshot newer than the recorded shipment, received after it. Uploading an older file again cannot free that stock. Older, equal or undated updates cannot replace a position with a known newer timestamp; missing source times leave dispatched reservations in place. GET /api/v1/inventory returns both snapshotAt and the local receipt time, updatedAt.
Push URLs
When your system can only be given a URL (a webhook, a Zapier or Make step, an export job), ask for a push URL (brand page or brand portal, Feeds). It's shown once and reaches only the brand it was made for. Send the payload as the body, up to 10MB:
curl -X POST "https://nextra360.com/api/v1/push/n360p_..." \
-H "Content-Type: application/json" \
-d '[{"sku":"ACME-SOFA-01","warehouse":"Dallas DC","available":42}]'
# or keep the token out of the URL
curl -X POST "https://nextra360.com/api/v1/push" -H "Authorization: Bearer n360p_..." \
-H "Content-Type: text/csv" --data-binary @inventory.csv202 with the batch (applied, or waiting for review for price books), 422 when the data can't be read, 401 for any unknown or removed URL, 413 over 10MB, 429 past 60 pushes a minute. Add ?kind= to send another kind, ?kind=auto to detect it, and ?records_path= when the records sit somewhere unusual. Treat the URL like a password: anyone holding it can send data for your brand. Removing it on the feeds list stops it at once.
Feeds from your API
A scheduled feed can read your own API, not just a file. Paste the URL, test it, and the wizard shows what it found before anything is saved.
- Sign-in styles: none, an API token (
Authorization: Bearer), a key in a header you name (X-API-Key), username and password (Basic), or a key as a URL parameter (?api_key=). Keys are stored encrypted, sent only to your host, and a URL-parameter key is blanked out of every log, error and batch name. - Finding the records: a JSON or XML response can wrap its list anywhere:
data,results[0].rows, GraphQLedges[].node, repeated XML elements. We find it and show the path; you can pin another. Nested objects become dotted columns (price.amount), and a product's variants (or a shipment's lines) become one row each when they carry the SKUs. - Paging: followed automatically, up to 20 pages a run: a
Link: rel="next"header, a next link in the body (next,links.next,@odata.nextLink,nextRecordsUrl), a cursor (next_cursor,nextPageToken,page_info), Stripe-stylehas_more, or page and offset counters. Every page must be on the same site as the first, and all pages together stay under 20MB. - XML: product exports, Google Merchant feeds and XML ship notices read like JSON: namespaces dropped, attributes become columns, values kept as text (a SKU like 00123 stays 00123). Documents that declare their own entities are refused.
- Columns: matched by name, then checked against the values (a column of ids is never taken as prices). If your workspace has AI turned on, it can suggest the fields still missing; every suggestion is checked against your data before it's offered.
EDI
X12 832 (price/sales catalog), 846 (inventory) and 856 (ship notice) are read by segment: SKUs from LIN (VN, VP, SK, MG, BP qualifiers), UPCs from LIN UP/EN/UK, prices from CTP (WHL/NET/UCP/CON dealer, MSR/RES/RTL/SLP retail), quantities from QTY (33 available, 17 on hand, 02 committed), warehouses from N1, PO numbers from PRF, carriers from TD5, tracking from REF*CN or BM. Send one transaction type per file, by upload, the ingest endpoint, or a feed URL.
Outbound purchase orders use the trading-partner and EDI message endpoints. Configure an existing Stedi partnership/transaction setting, or an HTTPS gateway implementing the documented callback contract. Preview the brand's X12 850, enable the test connection and queue it with a stable idempotency key. A 202 response means the immutable message is queued.
Track gateway submission, transport delivery and functional 997 acknowledgment separately. Stedi delivery status is read from the provider; a 997 imported by an authenticated user is labeled imported evidence. Neither a successful transport nor an accepted 997 confirms the commercial order. A receipt, mode or delivery mismatch requires reconciliation.
Generic gateway receipts use x-nextra-timestamp in Unix seconds and x-nextra-signature: sha256=..., calculated over the timestamp, a dot and the exact raw body with the partner's receipt secret. The timestamp must be within five minutes. Credentials are never returned by these APIs.
Live trading-partner onboarding and certification still happen with the provider and partner. Nextra360 does not implement direct AS2 cryptography or verify signed MDNs. Automatic X12 860 amendments are outside this release; an attempted PO cannot be silently changed or cancelled locally.
Platform billing integration
When an operator configures and enables Stripe, tenant admins can open hosted Checkout and the customer portal from Billing settings. Plan prices, customer binding and return URLs are selected on the server. This subscription pays for the platform; existing manual invoices and merchandise credit memos stay separate.
The provider endpoint is POST https://nextra360.com/api/billing/webhook, outside the versioned API. It accepts Stripe-signed snapshot events and requires Stripe-Signature over the exact raw request bytes. It does not use a tenant API key. Duplicate events are recorded once, and current provider state determines the subscription status even when events arrive out of order. A Checkout return does not prove payment.
Disabled billing or retryable reconciliation failures return 503 for provider retry. Missing or invalid signatures return 400; payloads over 1 MiB return 413. The configured Stripe account still requires test-mode acceptance and owner-approved live setup before live billing begins.
