Skip to content

Accounts ​

7 reads, no writes, on train 2026-11. Scopes: accounts:read.

OperationMethodScopePath
List edi documentsGETaccounts:read/api/v1/wholesale/edi/documents
Every trading accountGETaccounts:read/api/v1/wholesale/retailers
The brand's contacts at one accountGETaccounts:read/api/v1/wholesale/retailers/{partner_id}/contacts
One account's stock positionGETaccounts:read/api/v1/wholesale/retailers/{partner_id}/overview
One account's productsGETaccounts:read/api/v1/wholesale/retailers/{partner_id}/products
The values and ranges the account products table can be filtered onGETaccounts:read/api/v1/wholesale/retailers/{partner_id}/products/filters
What this account should be sent nextGETaccounts:read/api/v1/wholesale/retailers/{partner_id}/replenishment-recommendations

List edi documents ​

GET /api/v1/wholesale/edi/documents

Scopes: accounts:read

Every EDI document this organisation has exchanged with its accounts: purchase orders (850) in, acknowledgements (855), shipping notices (856) and invoices (810) out, and the inventory (846) and sell-out (852) reports that arrive on the same connection. Each row says which account it belongs to, which order it became or answered, what state it reached, and the sentence behind that state where it has one, so a file that was refused or an acknowledgement a network would not take is readable here rather than in the network's own console. network says which lane a document came through, and it is also the filter: this log holds every lane an order can arrive on, so ask for network=sps_commerce for the EDI lane alone. Read only: documents are made by the acts that make them, never posted here.

OptionalInWhat it is
trading_partner_idqueryOne account's documents only.
document_typequeryOne kind of document only, by its X12 number.
directionqueryDocuments that arrived (inbound) or that Tightly sent (outbound).
statequeryDocuments in this state only.
networkqueryThe lane the document came through.
offsetqueryRows to skip before the page starts.
limitqueryRows on the page.
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/edi/documents" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "filtered_max_size": 2,
    "max_size": 50,
    "offset": 0,
    "rows": [
      {
        "account": {
          "name": "Coastline Department Stores",
          "trading_partner_id": "tp_coastline"
        },
        "control_number": "CDS-90114",
        "direction": "outbound",
        "document_id": 42,
        "document_type": "855",
        "file_path": "in/855-CDS-90114.xml",
        "network": "sps_commerce",
        "order": {
          "name": "ORD-00000412",
          "order_id": "ord_01JQ8ZK7C4N2R9V6T3M0X5A1BD"
        },
        "received_at": null,
        "sent_at": "2026-09-05T17:30:00+00:00",
        "sentence": null,
        "state": "sent"
      },
      {
        "account": {
          "name": "Coastline Department Stores",
          "trading_partner_id": "tp_coastline"
        },
        "control_number": "CDS-90114",
        "direction": "inbound",
        "document_id": 41,
        "document_type": "850",
        "file_path": "out/PO/PO584615-1-v7.7-BulkImport.xml",
        "network": "sps_commerce",
        "order": {
          "name": "ORD-00000412",
          "order_id": "ord_01JQ8ZK7C4N2R9V6T3M0X5A1BD"
          …
        }
      }
    ]
  }
}

What it refuses

  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes: Accounts is sold with Tightly Connect on Essentials+ and this organisation's plan does not include it; scope_missing: the key does not hold Accounts; account_mismatch: a key issued to one account named another.
  • 429

Try it in the reference

Every trading account ​

GET /api/v1/wholesale/retailers

Scopes: accounts:read

Every trading account, with the identity a sell-out write and an order-book read both name an account from: its id, the account's own buyer reference, its name, its sales channel, transit time, when its data last synced, its standing terms (tier, fill-rate target, cancellation term and notice days), the next estimated order date, the trading figures read off its own reports, and portal_seats, the account's side of the buyer's portal: how many buyers hold a live seat, how many invitations are still unopened, and when any of them last opened it.

OptionalInWhat it is
retailer_idsqueryRestrict to these accounts, comma-separated.
variant_idqueryOnly accounts that carry this variant, which accounts stock it.
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/retailers" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "retailers": [
      {
        "account_tier": 1,
        "buyer_id": "SLF-4471",
        "cancellation_notice_days": 30,
        "cancellation_term": "window",
        "cancellation_term_note": null,
        "fill_rate_target_pct": 97,
        "id": "tp_00417",
        "last_data_synced_at": "2026-09-03T02:14:00+00:00",
        "name": "Selfridges",
        "next_estimated_sale_order_date": "2026-09-21",
        "next_estimated_sale_order_in_weeks": 2,
        "portal_seats": {
          "accepted": 2,
          "invited": 1,
          "last_opened_at": "2026-09-03T16:40:00+00:00"
        },
        "sales_channel_id": "61240442",
        "sales_velocity_per_week": 184.5,
        "sell_through_rate": 0.86,
        "total_skus": 412,
        "transit_time_days": 4
      }
    ]
  },
  "message": {
    "desc": "OK",
    "service": "wholesale",
    "severity": "INFO"
  }
}

What it refuses

  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes when Accounts is sold with Essentials+ and this organisation's plan does not include it; scope_missing when the key does not hold Accounts; organization_mismatch when the path names an organisation that is not the key's; ip_not_allowed when the caller's address is outside the key's allowlist.
  • 429

Try it in the reference

The brand's contacts at one account ​

GET /api/v1/wholesale/retailers/{partner_id}/contacts

Scopes: accounts:read

The brand's contacts at one account and the email domains that make a thread theirs: the account's name, its recorded domains, and one entry per contact with name, email, phone, role, department, contact type, last interaction date and whether they are the main contact.

RequiredInWhat it is
partner_idpathThe account. An id, never a name. Duplicate account names are ordinary in apparel.
OptionalInWhat it is
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/retailers/<partner_id>/contacts" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "contacts": [
      {
        "contact_type": "buyer",
        "department": "Womenswear",
        "email": "morgan@retailer.example",
        "id": 4471,
        "is_main": true,
        "last_interaction_date": "2026-08-28",
        "name": "Morgan Example",
        "phone": null,
        "role": "Buyer"
      }
    ],
    "domains": [
      "retailer.example"
    ],
    "domains_reason": null,
    "name": "Selfridges",
    "trading_partner_id": "tp_00417"
  },
  "message": {
    "desc": "OK",
    "service": "wholesale",
    "severity": "INFO"
  }
}

What it refuses

  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes when Accounts is sold with Essentials+ and this organisation's plan does not include it; scope_missing when the key does not hold Accounts; organization_mismatch when the path names an organisation that is not the key's; ip_not_allowed when the caller's address is outside the key's allowlist; account_mismatch when a key issued to one account names another in the path, and the sentence names both accounts.
  • 429

Try it in the reference

One account's stock position ​

GET /api/v1/wholesale/retailers/{partner_id}/overview

Scopes: accounts:read

One account's stock position: the estimated stock on hand for the current week, the timeline behind it, the forward projection, and the last and next delivery either side of today.

RequiredInWhat it is
partner_idpathThe account. An id, never a name. Duplicate account names are ordinary in apparel.
OptionalInWhat it is
variant_idqueryScope the overview to one variant.
product_idqueryScope the overview to every variant of one product.
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/retailers/<partner_id>/overview" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "current_stock": {
      "end_date": "2026-09-06",
      "estimated_stock_on_hand": 302,
      "start_date": "2026-08-31"
    },
    "forecasted_stock_timeline": [
      {
        "date": "2026-09-07",
        "on_hand": 218
      }
    ],
    "last_delivery": {
      "date": "2026-08-11",
      "quantity": 600
    },
    "next_delivery": {
      "date": "2026-09-22",
      "quantity": 800
    },
    "replenishment_date": null,
    "replenishment_qty": null,
    "stock_timeline": [
      {
        "date": "2026-08-24",
        "on_hand": 411
      },
      {
        "date": "2026-08-31",
        "on_hand": 302
      }
    ]
  },
  "message": {
    "desc": "OK",
    "service": "wholesale",
    "severity": "INFO"
  }
}

What it refuses

  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes when Accounts is sold with Essentials+ and this organisation's plan does not include it; scope_missing when the key does not hold Accounts; organization_mismatch when the path names an organisation that is not the key's; ip_not_allowed when the caller's address is outside the key's allowlist; account_mismatch when a key issued to one account names another in the path, and the sentence names both accounts.
  • 429

Try it in the reference

One account's products ​

GET /api/v1/wholesale/retailers/{partner_id}/products

Scopes: accounts:read

A page of one account's products: the brand's unit cost and both prices beside the account's own on-hand quantity, incoming units, weeks of cover and sell-through rate, with the variant's identity, supplier and velocity figures.

RequiredInWhat it is
partner_idpathThe account. An id, never a name. Duplicate account names are ordinary in apparel.
OptionalInWhat it is
limitqueryRows per page.
offsetqueryRows to skip.
searchqueryMatches product title, variant title, SKU, product id or variant id.
filter_argsqueryA JSON array of {key, operation, value}.
sort_argsqueryComma-separated columns; - for descending.
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/retailers/<partner_id>/products" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "filtered_max_size": 412,
    "offset": 0,
    "rows": [
      {
        "category": "Knitwear",
        "default_supplier_name": "Porto Knits",
        "health": "caution",
        "product_id": "4410092",
        "product_image": "https://cdn.example.com/terry-crew.jpg",
        "product_title": "Terry Crew",
        "product_type": "Knitwear",
        "production_type": "buy_only",
        "retailer_incoming_units": 120,
        "retailer_on_hand": 42,
        "retailer_weeks_of_cover": 2,
        "sales_velocity_30_days": 3.6,
        "sales_velocity_7_days": 4.1,
        "sales_velocity_90_days": 3.2,
        "sell_in_price": 29.5,
        "sell_out_price": 79,
        "sell_out_velocity_per_week": 21,
        "sell_through_rate": 0.86,
        "sku": "TB-CREW-BLK-M",
        "supplier_details": [],
        "supplier_id": "sup_0031",
        "unit_cost": 12.4,
        "variant_id": "44100920011",
        "variant_title": "Black / M"
      }
    ],
    "size": 1
  },
  "message": {
    "desc": "OK",
    "service": "wholesale",
    "severity": "INFO"
  }
}

What it refuses

  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes when Accounts is sold with Essentials+ and this organisation's plan does not include it; scope_missing when the key does not hold Accounts; organization_mismatch when the path names an organisation that is not the key's; ip_not_allowed when the caller's address is outside the key's allowlist; account_mismatch when a key issued to one account names another in the path, and the sentence names both accounts.
  • 429

Try it in the reference

The values and ranges the account products table can be filtered on ​

GET /api/v1/wholesale/retailers/{partner_id}/products/filters

Scopes: accounts:read

The values and ranges the account products table can be filtered on: a flat map keyed by filter key, carrying the distinct categorical values this account's variants actually carry and a {min, max} pair for each numeric range.

RequiredInWhat it is
partner_idpathThe account. An id, never a name. Duplicate account names are ordinary in apparel.
OptionalInWhat it is
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/retailers/<partner_id>/products/filters" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "category": [
      "Knitwear",
      "Outerwear"
    ],
    "production_type": [
      "buy_only",
      "manufacturable"
    ],
    "retailer_incoming_units": {
      "max": 2400,
      "min": 0
    },
    "retailer_on_hand": {
      "max": 1840,
      "min": 0
    },
    "retailer_weeks_of_cover": {
      "max": 41,
      "min": 0
    },
    "sales_velocity": {
      "max": 18.4,
      "min": 0
    },
    "sell_in_price": {
      "max": 190,
      "min": 12
    },
    "sell_out_price": {
      "max": 420,
      "min": 29
    },
    "supplier": [
      {
        "supplier_id": "sup_0031",
        "supplier_name": "Porto Knits"
      }
    ]
    …
  }
}

What it refuses

  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes when Accounts is sold with Essentials+ and this organisation's plan does not include it; scope_missing when the key does not hold Accounts; organization_mismatch when the path names an organisation that is not the key's; ip_not_allowed when the caller's address is outside the key's allowlist; account_mismatch when a key issued to one account names another in the path, and the sentence names both accounts.
  • 429

Try it in the reference

What this account should be sent next ​

GET /api/v1/wholesale/retailers/{partner_id}/replenishment-recommendations

Scopes: accounts:read

What this account should be sent next, highest composite score first: one row per variant with the recommended quantity, the impact level, the replenishment date, the destination location and the default supplier, and production_type saying which act follows, a basket for a bought item or a manufacturing order for a made one.

RequiredInWhat it is
partner_idpathThe account. An id, never a name. Duplicate account names are ordinary in apparel.
OptionalInWhat it is
limitqueryHow many rows to return. Clamped to 1 to 100.
Tightly-VersionheaderThe date train to answer on.
bash
curl "https://api.app.tightly.io/api/v1/wholesale/retailers/<partner_id>/replenishment-recommendations" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What it answers

json
{
  "data": {
    "rows": [
      {
        "composite_score": 0.82,
        "id": 90114,
        "impact_level": "high",
        "location_id": "loc_0004",
        "location_name": "London DC",
        "product_id": "4410092",
        "product_image": "https://cdn.example.com/terry-crew.jpg",
        "product_title": "Terry Crew",
        "production_type": "buy_only",
        "recommended_quantity": 240,
        "replenishment_date": "2026-09-21",
        "sku": "TB-CREW-BLK-M",
        "supplier_id": "sup_0031",
        "supplier_name": "Porto Knits",
        "variant_id": "44100920011",
        "variant_title": "Black / M"
      }
    ]
  },
  "message": {
    "desc": "OK",
    "service": "wholesale",
    "severity": "INFO"
  }
}

What it refuses

  • 400 limit is not an integer.
  • 401 key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
  • 403 plan_excludes: "This organisation's plan does not include Tightly Connect. It is sold with Essentials+." The key may not reach this operation. plan_excludes when Accounts is sold with Essentials+ and this organisation's plan does not include it; scope_missing when the key does not hold Accounts; organization_mismatch when the path names an organisation that is not the key's; ip_not_allowed when the caller's address is outside the key's allowlist; account_mismatch when a key issued to one account names another in the path, and the sentence names both accounts.
  • 429

Try it in the reference

Tightly API, version 2026-11.