atouch API Overview
With atouch API, you can read and write product, order, and customer data from the existing atouch (Shop / Admin) platform through standard OpenAPI 3.1 + OAuth 2.1.
It is served in production at https://api.developers.atouch.jp. Alongside read access to products, orders, and customers, write access for inventory, shipping, and catalog management is available (all idempotent). See the tables below for details.
Access requires issued client credentials. Contact the operator to get started.
Available APIs (ReadOnly)
| Area | Contents | Required scope |
|---|---|---|
| Items / Categories | Item list & detail, categories, delivery companies, own shop. Incremental fetch via updated_since, exact sku lookup. Stock comes with the quantity held by checkouts in progress (reserved_inventory) | read_items / read_users |
| Orders | Order header, line items, shipments (buyer PII excluded). Incremental fetch via updated_since (for order polling). Line items include the purchased variant (variant); shipments include the tracking number, its registration time and the expected delivery date | read_orders |
| Order buyer PII | Purchaser / recipient name, address, phone | read_orders_pii |
| Customers | LINE identity, tags, orders | read_customers |
| Customer PII | Name / address / phone / email / gender | read_customers_pii |
Available APIs (Write)
| Area | Contents | Required scope |
|---|---|---|
| Inventory reservations | Reserve (hold) → confirm / release. Availability is checked atomically — no overselling. Reservations auto-expire via TTL (default 15 min) | write_reservations |
| Shipping status | Shipping status transitions (prepared → partial_shipped → shipped → re_shipped / returned), tracking number registration / correction | write_shipping |
| Stock updates | Set item stock to an absolute value (0–99999), adjust by a delta, or set the total (the API subtracts units held by checkouts in progress). Items with variants require variant_id (set items are derived from their components) | write_items |
| Items | Create items (all kinds: normal / gift / ticket / free ticket / pre-sale ticket / set) and edit existing items (partial update, recorded in the merchant change log) | write_items |
| Categories | Create (up to 2 levels; sort auto-assigned to the end) and edit (name / status / sort) | write_items |
| Item images | Register or replace images by URL (JPEG/PNG, validated by actual bytes), reorder and delete. Create → image → publish completes via API alone | write_items |
| Variants | Declare axes (colour, size, …) and combinations at item creation; afterwards add and edit variants (end of sale = status: inactive). Axes are fixed at creation | write_items |
All write endpoints require the Idempotency-Key header (resending the same key safely replays the result).
Only the operations that the existing admin UI itself logs are written to the merchant's change history — namely item edits, stock updates, and shipping status changes. Item creation, category operations, image operations, and variant operations are not recorded there, because the existing admin UI does not record them either (we do not invent history the platform never had). All API operations are captured separately in our own audit log.
Basics
- Base URL:
https://api.developers.atouch.jp - Protocol: HTTPS only
- Format:
application/json; charset=utf-8 User-Agentheader (required): sendyour-integration/version (+contact URL), for examplemy-connector/1.2 (+https://example.com/contact). Requests without it are rejected with403(HTML body) before they reach the API. Some HTTP clients and worker runtimes do not set one by default, so set it explicitly- Datetime (responses): ISO 8601 / RFC 3339 in UTC (e.g.
2026-06-01T03:00:00Z)
Datetime (requests) comes in two flavors:
・Cursor timestamps (updated_since) — any offset is accepted (Zand+09:00denote the same instant)
・Business timestamps (sell_from/sell_by/cancel_by, ticket fields) —YYYY-MM-DD HH:mm(:ss)only. Supplying an offset returns 400. The value is interpreted as the shop's local (JST) wall-clock time
For incremental sync, pass theupdated_atvalue from the response straight back as the next cursor. Deriving it from your own clock invites timezone drift. - Money:
{ "amount": 3200, "currency": "JPY" } - Fields that may be omitted:
varianton order line items andreserved_inventoryon items (including the per-variant value) are left out of the response entirely when they could not be retrieved. That is different fromnull(no variant) or0(nothing held). When the key is absent, do not read it as either — retry later. - Envelope: collections use
{ "data": [...], "pagination": {...} }and errors use{ "error": { code, message } }.
Single resources generally use{ "data": {...} }, but stock updates, image create/reorder/delete, and reservation endpoints return a bare object for backward compatibility (e.g.{ "item_id": "1", "inventory": 20, "previous_inventory": 5 }). See each endpoint's response example.
Rate limits
Limits are applied per client (client_id). Defaults:
| Type | Sustained rate | Burst |
|---|---|---|
| Reads (GET / HEAD) | 5 req/sec | 20 |
| Writes (POST / PATCH / PUT / DELETE) | 1 req/sec | 4 |
- On exceeding a limit the API returns
429({ "error": { "code": "rate_limited" } }) withRetry-After(seconds) plusX-RateLimit-Limit/X-RateLimit-Remaining/X-RateLimit-Reset. Wait forRetry-Afterbefore retrying. - Burst is how many calls you can send back-to-back; the sustained rate is the long-run ceiling. Writes are set to 1/5 of reads.
- For bulk imports (e.g. an initial sync from another commerce platform), size your run against the write rate. As a guide, 1,000 items × (create + image + publish) ≈ 3,000 calls ≈ 50 minutes. Increasing concurrency does not raise the sustained rate.
- If your integration consistently needs more, ask us about a per-client increase.
Working with large volumes
We do not provide bulk create/update endpoints. Call the individual endpoints repeatedly.
- Attach an
Idempotency-Keyper item so you can safely retry and resume if the connection drops (replays of the same key are not processed twice) - On
429, wait forRetry-Afterbefore continuing - Hundreds to thousands of items complete in a practical amount of time within the limits above
⚠️ If repeated calls cannot meet your requirements, tell us the volume and frequency. We will consider bulk processing based on actual demand.
Integrating with external systems
Notes for two-way synchronisation with another commerce or inventory system.
inventoryis the quantity left after subtracting stock held by checkouts in progress. Stock is deducted as soon as a buyer starts paying and is returned within minutes if the payment does not complete. The held quantity is returned asreserved_inventory(this is unrelated to the stock reservations listed above). When comparing with the total you hold on your side, useinventory + reserved_inventory. The two values are read separately, so a read taken at the moment a hold changes can be off by that hold once. If you see a difference, read again and confirm the same difference before acting on it.- To bring the total to X, use
total_inventory. Inside the update, the API locks the stock row, counts the units currently held by checkouts in progress, and stores total − held. The total stays correct whether those holds are later completed or released. Steps:
① Read the item and note the total T (inventory + reserved_inventory). For items with variants, read the item detail for per-variant values
② Then import Atouch-side orders and decide X. Re-read orders from slightly before your last cursor (about 1 minute) and de-duplicate by order ID, because an order's update time is set shortly before it is committed. Do not countinitorders as sales
③ Send{"total_inventory": X, "expected_total_inventory": T}. Do not send it together withinventoryoradjustment(environments that do not support it drop unknown fields and would applyinventory)
④409 total_inventory_changedmeans the total changed after ① (a sale completed or someone rewrote the stock); nothing was written. Start over from ① with a newIdempotency-Key.409 inventory_busymeans the stock row was in use (e.g. a checkout in progress) and nothing was written; resend afterRetry-Afterwith the sameIdempotency-Key, or try in the next cycle
⚠️ A sale that completed before ① and has not been imported yet is not caught by this check (T already reflects it, so the condition matches). Keep the order of ②. If you did not receive a response, resend with the sameIdempotency-Key(a new key recounts and may overwrite sales made in between). If the response in ① lacks thereserved_inventorykey, skip that cycle. Ifinventory + reserved_inventoryin the response exceeds X, the total was lower than the held quantity (stock is set to 0); keep sending the same way in the next cycles and it converges. - Sales deltas can be sent with
adjustment. An absolute value (inventory) overwrites the sellable quantity as is and also overwrites holds in progress (stock ends up too high once those holds are returned). Use absolute values only for the initial load before the item goes on sale and to start tracking stock (sendingtotal_inventoryfor an item whose stock is not tracked returns422 unlimited_inventory). - Where
total_inventoryis not available (StockUpdateRequestin/openapi.jsonhas nototal_inventory, so sending it alone returns400; ortotal_inventoryreturns503 capability_not_enabled, meaning it is not enabled yet — nothing is written in either case), sendadjustment = X − (inventory + reserved_inventory). The two values are read separately, so if you see a difference, read again and confirm the same difference first. Do not use this formula when thereserved_inventorykey is absent, or for items whoseinventoryisnull. A sale that completes between your order import and your item read is cancelled out by the formula (stock stays one sale too high until the next reconciliation), so reconcile during quiet hours. Ifadjustmentfails with422 negative_inventory, do not drop the delta: import orders, read the item again, recompute, and send with a newIdempotency-Key. Only if X is still lower thanreserved_inventoryafter re-reading, writeinventory: 0, and always reconcile again about 10 minutes later. - Identify the purchased variant by
varianton the line item. The line item'sskuis the SKU currently set on the parent item, so it is the same for every variant of that item. Whenvariant.idisnull(the variant was deleted, its SKU or name changed, several variants share the SKU, and so on), match onvariant.skuandvariant.name. Whenvariant.skuisnull(no SKU was set at purchase time), match onvariant.name, and hand it to a person if that does not identify a single variant. - Cancelled orders are
voidandclosed. Neither returns stock automatically. initmeans the order was never completed — the checkout did not finish, or the payment failed. Those created by the current checkout normally carry a zero amount and no line items; those created in 2024 or earlier carry an amount. The order list returnsinitorders too, so do not import them as valid orders. When the checkout completes, the status changes under the same order ID and the amounts and line items are filled in. If you mark an order as processed while it isinit, you will miss it.- Origin of image fetches (allowlist these if your image host restricts access):
| Item | Value |
|---|---|
| User-Agent | atouch-api/1.0 (+https://developers.atouch.jp) |
| Accept | image/jpeg,image/png;q=0.9,*/*;q=0.1 |
If you need to allowlist by source IP address, please contact us and we will share the current addresses. They are not published here because they can change with environment or infrastructure updates.
Handling of personal data (PII)
Buyer PII (name, address, phone, email, etc.) is returned only to tokens that hold the corresponding PII scope. Without it, those fields are omitted from the response entirely. Card numbers and payment-gateway tokens are never returned under any scope.
Continue to Getting Started to obtain a token and make your first call.