A forklift moving boxed furniture through a distribution center

Developers

Connect your data

Three ways in, one pipeline. Whatever you send becomes a batch with an audit trail, and every number reps show dealers traces back to it.

  1. 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.

  2. 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.

  3. 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.xlsx

The 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/pingCheck a key and see what it can reach.
POST/api/v1/ingestSend 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/pushThe 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/productsCreate or update catalog items in bulk, JSON. Prices in dollars.
GET/api/v1/productsList products with inventory, filtered by sku, category or lifecycle.
POST/api/v1/inventoryUpsert inventory positions by SKU and warehouse. Include snapshotAt from the source system to reconcile dispatched stock reservations.
GET/api/v1/ordersStore 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}/confirmConfirm 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}/acknowledgeWorkspace 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}/adjustmentsReturns, 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-partnersRead 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/messagesRead 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/asnFull 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/salesDealer sell-through (POS) by period. Refreshes each dealer's 12-month sales and trend.
POST/api/v1/price-bookLegacy: 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
nameProduct name. Also: name, product name, item name, title, description, product description, item description, short description
dealerPriceDealer price. Also: dealer price, dealer, dealer cost, dlr, dlr price, dlr cost, wholesale, wholesale price
msrpMSRP. Also: msrp, retail, retail price, suggested retail, suggested retail price, list price, list, srp
categoryCategory. Also: category, cat, product category, product type, group, type, dept, department
imageUrlImage URL. Also: image, image url, photo, photo url, img, img url, picture, picture url
collectionCollection. Also: collection, series, line, family, group name
descriptionLong description. Also: long description, full description, details, marketing copy, body
sellingPointsSelling points. Also: selling points, features, key features, highlights, bullets, bullet points, benefits, claims
lifecycleLifecycle. Also: lifecycle, status, item status, product status, availability status
upcUPC / GTIN. Also: upc, gtin, ean, barcode, upc code
rtoWeeklyRental weekly rate. Also: rto weekly, weekly rate, weekly, rental weekly, rent weekly, weekly rental, rto weekly cents
rtoTermWeeksRental term (weeks). Also: rto term, term weeks, rental term, term, weeks

Inventory

snapshotAtInventory 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
nodeWarehouse. Also: warehouse, node, location, dc, distribution center, whse, facility, ship from
onHandOn hand. Also: on hand, qoh, qty on hand, quantity on hand, onhand
allocatedAllocated. Also: allocated, committed, reserved, qty allocated, qty committed
inboundInbound. Also: inbound, on order, incoming, qty on order, in transit, po qty
nextReceiptDateNext receipt date. Also: next receipt, next receipt date, eta, due date, expected date, restock date, arrival date, next available
transitDaysTransit days. Also: transit days, lead time, lead time days, ship days, transit

Ship notices

poNumberPO number. Also: po, po number, po #, purchase order, purchase order number, customer po, po no
orderIdOrder id. Also: order id, order, order number, order #, sales order
shipmentIdShipment id. Also: shipment, shipment id, shipment number, asn, asn number, bol, bill of lading, manifest
carrierCarrier. Also: carrier, scac, carrier name, ship via, shipper
trackingNumberTracking number. Also: tracking, tracking number, tracking #, tracking no, pro, pro number
shipDateShip date. Also: ship date, shipped, shipped date, date shipped, ship dt
expectedDeliveryDateExpected delivery. Also: expected delivery, expected delivery date, delivery date, eta, est delivery, estimated delivery
skuSKU. Also: sku, item, item no, item number, item code, item #, model, model no
quantityQuantity shipped. Also: quantity shipped, qty shipped, shipped qty, quantity, qty, units
deliveredAtDelivered date. Also: delivered at, delivered date, date delivered, delivered on, pod date, actual delivery, actual delivery date
deliveredDelivered (yes/no). Also: delivered, is delivered, delivery confirmed
accountNumberDealer account #. Also: account, account number, account #, account no, acct, acct #, customer number, customer #

Dealer sales (POS)

accountNumberDealer account #. Also: account, account number, account #, account no, acct, acct #, customer number, customer #
dealerNameDealer 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
periodStartPeriod 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
unitsUnits. 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.

  1. request-return: use a stable reference, reason and proposal-line IDs from shipment progress. Request only delivered units not already assigned to another return.
  2. authorize-return or reject-return: identify the pending return by its return ID.
  3. receive-return: identify the return and its return-line IDs, with a unique receipt reference and quantities received now.
  4. issue-credit: identify received return-line quantities not already credited. Amounts use original sale prices.
  5. settle-credit: supply the credit memo ID, an external settlement reference and attested: true. This records a settlement made outside Nextra360; it does not send money or issue a card refund.
  6. 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.csv

202 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, GraphQL edges[].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-style has_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.