Skip to main content

Changelog

Changes to the public atouch API (/v1) contract, newest first. Backward-compatible additions such as new response fields ship without notice, as described in Versioning & deprecation. This page is where you can see what shipped.

  • AddedNew fields or endpoints
  • ChangedBehavior change (backward compatible)
  • FixedBug fix
  • DocsBehavior unchanged

2026-10-22​

The 429 response is now declared on every endpoint, and required headers and token-endpoint behavior are documented.

Docs

429 (rate limited) declared on every endpoint​

All endpoints

The spec (OpenAPI) did not declare 429, so generated SDKs treated it as an unexpected response. Behavior is unchanged: on 429, retry after Retry-After (seconds).

Docs

413 (payload too large) declared on endpoints that take a request body​

All endpoints that take a request body

Request bodies over 1 MiB return 413 (payload_too_large). Normal use does not come close to this size.

Docs

The User-Agent header is required​

All endpoints

Requests without a User-Agent are rejected with 403 (HTML body) before they reach the API. This was already the behavior but was not documented. Send something like your-integration/1.0 (+https://example.com/contact).

Changed

Token endpoint no longer distinguishes authentication failure reasons​

POST/v1/oauth/tokenPOST/v1/oauth/revoke

Unknown client_id, disabled clients, and wrong client_secret all return the same 401 (invalid_client, client authentication failed). Repeated failures in a short time return 429 (rate_limited); retry after Retry-After. code_verifier must be 43-128 unreserved characters (A-Z a-z 0-9 - . _ ~).

Added

Access tokens can be revoked at /v1/oauth/revoke​

POST/v1/oauth/revoke

Pass an access token (JWT) as token (token_type_hint=access_token) to revoke just that token before it expires. Environments that do not offer this return 400 (unsupported_token_type). Refresh-token revocation is unchanged.

2026-10-09​

Added read fields for stock and orders. Existing fields keep their values and types.

Check your integration if you set stock with an absolute value (inventory). inventory is the count after stock held by checkouts in progress has been deducted. Sending your total on hand as-is overstates stock by the held amount. To match a total, send the difference from the total you read as adjustment.

Added

Items now return stock held by checkouts in progress​

GET/v1/itemsGET/v1/items/{id}

Stock is deducted as soon as a buyer starts paying. reserved_inventory returns that amount. Your total on hand is inventory + reserved_inventory.

FieldTypeDescription
+ reserved_inventoryinteger | nullStock held by checkouts in progress. null when inventory is null. The key is omitted when the value could not be read
+ variants[].reserved_inventoryinteger | nullHeld stock per variant. Returned by the item detail
GET /v1/items/{id} response (excerpt)
  {    "id": "1487",    "inventory": 9,+   "reserved_inventory": 1,    "variants": [      {        "id": "2",        "inventory": 4,+       "reserved_inventory": 0      }    ]  }
Added

Order line items now return the purchased variant​

GET/v1/orders/{id}/items

A line item's sku is the SKU currently set on the parent item. Use variant to identify what was bought.

FieldTypeDescription
+ variantobject | nullThe purchased variant. null for items without variants. The key is omitted when the value could not be read
+ variant.idstring | nullID of the matching current variant. null when it cannot be determined
+ variant.skustring | nullThe variant's SKU at the time of purchase
+ variant.namestringThe variant's name at the time of purchase
One line item from GET /v1/orders/{id}/items (excerpt)
  {    "sku": "TS-001",+   "variant": {+     "id": "2",+     "sku": "TS-001-WH-M",+     "name": "白 / M"+   }  }
Added

Shipments now return when the tracking was registered and its delivery date​

GET/v1/orders/{id}/shipments
FieldTypeDescription
+ tracking_registered_atdate-time | nullWhen the tracking was registered (UTC). null does not mean the order has not shipped
+ tracking_delivery_datedate | nullThe delivery date registered on the tracking. Not the same as the buyer's requested date (delivery_date)
One shipment from GET /v1/orders/{id}/shipments (excerpt)
  {    "delivery_date": "2026-10-04",    "tracking_number": "1234-5678-9012",+   "tracking_registered_at": "2026-10-01T03:00:00.000Z",+   "tracking_delivery_date": "2026-10-03"  }
Docs

Clearer descriptions for stock, line items, shipments and order status​

GET/v1/itemsPATCH/v1/items/{id}/stockGET/v1/ordersGET/v1/orders/{id}/itemsGET/v1/orders/{id}/shipments
SubjectBeforeAfter
inventoryCurrent stockCurrent stock, after deducting stock held by checkouts in progress
inventory in a stock updateSets an absolute valueSets an absolute value, overwriting as given. Do not send your total on hand as-is
sku on a line itemProduct codeThe SKU currently set on the parent item, not the value at the time of purchase
tracking_numberTracking numberTracking number. When there are several, the first one registered
Order statusMeaning of each valueAlso notes that reward-exchange orders can be no_shipping from creation

Tracking numbers registered or corrected through the API, and shipping statuses changed through the API, now keep correct timestamps.

Fixed

Tracking numbers registered through the API now have a registration time​

POST/v1/orders/{id}/trackingsGET/v1/orders/{id}/shipments

Until now, tracking numbers registered through the API had no registration time, so tracking_registered_at was null. They are now recorded the same way as in the admin console. Tracking numbers registered through the API before this change stay null.

Fixed

Orders whose shipping status was changed through the API now appear in incremental fetches​

PATCH/v1/orders/{id}/statusGET/v1/orders

Until now, changing the shipping status through the API did not advance the order's update time, so the order did not appear when fetching with updated_since. The update time now advances the same way as in the admin console. If you fetch incrementally, changed orders appear again, so de-duplicate by order ID.

Fixed

Fixed delivery dates returned one day early when correcting tracking numbers​

PATCH/v1/orders/{id}/trackings/{tid}

When a correction omitted delivery_date, the response returned the date one day early. Sending the same delivery date was also recorded as a correction.

Stock updates can now take your total on hand as-is.

Added

Stock updates accept a total​

PATCH/v1/items/{id}/stock

Send your total on hand (sellable stock plus stock held by checkouts in progress) as total_inventory, and the API deducts the held amount before saving. It cannot be combined with inventory or adjustment.

FieldTypeDescription
+ total_inventoryintegerRequest. Total stock (0–99999). Items without managed stock return 422 (unlimited_inventory)
+ expected_total_inventoryintegerRequest. The total you read. Only valid together with total_inventory. If it differs from the current total, nothing is written and 409 (total_inventory_changed) is returned
+ reserved_inventoryintegerResponse. Returned only when total_inventory was sent. The held amount counted during the update
PATCH /v1/items/{id}/stock request
  # 読み取った値: inventory 9、reserved_inventory 1(総数 10)。倉庫を数えたら 12 だった- { "adjustment": 2 }+ { "total_inventory": 12, "expected_total_inventory": 10 }
Added

Two new 409 error codes for stock updates​

PATCH/v1/items/{id}/stock

Both are returned only when total_inventory was sent, and nothing was written. They need different handling, so branch on the code.

FieldTypeDescription
+ inventory_busy409The stock row was in use (for example, by a checkout in progress). Resend after Retry-After with the same Idempotency-Key
+ total_inventory_changed409The total changed after you read it. Read the item and orders again, recalculate, and send with a new Idempotency-Key

2026-09-25​

503 responses are now split into ones you can retry and ones retrying will not fix.

Changed

503 now uses two error codes​

Endpoints that return 503

A capability that is not offered in the environment returns capability_not_enabled; retrying will not succeed. Temporary failures still return service_unavailable, now with a Retry-After header.

SubjectBeforeAfter
Capability not offeredservice_unavailablecapability_not_enabled (no Retry-After; do not retry)
Temporary failureservice_unavailableservice_unavailable (with Retry-After; wait that long, then retry)
Response when calling a capability that is not offered
  HTTP/1.1 503 Service Unavailable  {    "error": {-     "code": "service_unavailable",+     "code": "capability_not_enabled",      "message": "…"    }  }

2026-09-24​

Fixed a bug that made item creation fail.

Fixed

Item creation no longer returns 500​

POST/v1/items

Requests that created an item returned 500 (internal_error). The request and response shapes are unchanged.

2026-08-29​

The item list now returns the sales period, and date-time inputs accept values with an offset.

Added

Sales period added to the item list​

GET/v1/items

status: active means the item is published, not that it can be bought. Items outside their sales period cannot be purchased. The item detail already returned these fields.

FieldTypeDescription
+ sell_fromdate-time | nullStart of the sales period
+ sell_bydate-time | nullEnd of the sales period. Items past this time cannot be purchased
One item from GET /v1/items (excerpt)
  {    "id": "1487",    "status": "active",+   "sell_from": "2026-08-01T00:00:00.000Z",+   "sell_by": "2026-08-31T14:59:59.000Z"  }
Changed

Date-time inputs accept values with an offset​

POST/v1/itemsPATCH/v1/items/{id}

Applies to date-time inputs such as the sales period (sell_from / sell_by). You can now write back the UTC value a response returned. The previous format still works.

SubjectBeforeAfter
2026-08-25 00:00:00AcceptedAccepted
2026-08-24T15:00:00.000Z400Accepted
Docs

Item status values are now described​

GET/v1/itemsGET/v1/items/{id}

The spec now states that active means published, not purchasable.

Validation errors (400) now say which fields are invalid.

Added

Validation errors (400) list the invalid fields​

All endpoints
FieldTypeDescription
+ error.issues[]arrayPresent only on validation errors (400). Lists each invalid field (path) with an explanation (message). The wording of message is not guaranteed
A 400 response
  {    "error": {      "code": "invalid_request",      "message": "…",+     "issues": [+       { "path": "limit", "message": "…" }+     ]    }  }
Docs

Variant responses now document item_id​

POST/v1/items/{id}/variantsPATCH/v1/items/{id}/variants/{variantId}

The field was already in the response but missing from the spec.

2026-08-26​

Date and time fields now declare a format in the spec.

Added

Date and time fields now declare a format​

OpenAPI spec

The spec now declares date-time for timestamps and date for dates in responses (with a few exceptions). Response values are unchanged.

Fixed a bug that made tracking updates fail.

Fixed

Tracking updates no longer return 500​

PATCH/v1/orders/{id}/trackings/{tid}

Requests that corrected a tracking number always returned 500. The request and response shapes are unchanged.

2026-08-25​

The atouch API (/v1) is now available.