Skip to main content

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)​

AreaContentsRequired scope
Items / CategoriesItem 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
OrdersOrder 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 dateread_orders
Order buyer PIIPurchaser / recipient name, address, phoneread_orders_pii
CustomersLINE identity, tags, ordersread_customers
Customer PIIName / address / phone / email / genderread_customers_pii

Available APIs (Write)​

AreaContentsRequired scope
Inventory reservationsReserve (hold) → confirm / release. Availability is checked atomically — no overselling. Reservations auto-expire via TTL (default 15 min)write_reservations
Shipping statusShipping status transitions (prepared → partial_shipped → shipped → re_shipped / returned), tracking number registration / correctionwrite_shipping
Stock updatesSet 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
ItemsCreate 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
CategoriesCreate (up to 2 levels; sort auto-assigned to the end) and edit (name / status / sort)write_items
Item imagesRegister or replace images by URL (JPEG/PNG, validated by actual bytes), reorder and delete. Create → image → publish completes via API alonewrite_items
VariantsDeclare axes (colour, size, …) and combinations at item creation; afterwards add and edit variants (end of sale = status: inactive). Axes are fixed at creationwrite_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-Agent header (required): send your-integration/version (+contact URL), for example my-connector/1.2 (+https://example.com/contact). Requests without it are rejected with 403 (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 (Z and +09:00 denote 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 the updated_at value 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: variant on order line items and reserved_inventory on items (including the per-variant value) are left out of the response entirely when they could not be retrieved. That is different from null (no variant) or 0 (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:

TypeSustained rateBurst
Reads (GET / HEAD)5 req/sec20
Writes (POST / PATCH / PUT / DELETE)1 req/sec4
  • On exceeding a limit the API returns 429 ({ "error": { "code": "rate_limited" } }) with Retry-After (seconds) plus X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset. Wait for Retry-After before 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-Key per item so you can safely retry and resume if the connection drops (replays of the same key are not processed twice)
  • On 429, wait for Retry-After before 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.

  • inventory is 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 as reserved_inventory (this is unrelated to the stock reservations listed above). When comparing with the total you hold on your side, use inventory + 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 count init orders as sales
    ③ Send {"total_inventory": X, "expected_total_inventory": T}. Do not send it together with inventory or adjustment (environments that do not support it drop unknown fields and would apply inventory)
    ④ 409 total_inventory_changed means the total changed after ① (a sale completed or someone rewrote the stock); nothing was written. Start over from ① with a new Idempotency-Key. 409 inventory_busy means the stock row was in use (e.g. a checkout in progress) and nothing was written; resend after Retry-After with the same Idempotency-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 same Idempotency-Key (a new key recounts and may overwrite sales made in between). If the response in ① lacks the reserved_inventory key, skip that cycle. If inventory + reserved_inventory in 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 (sending total_inventory for an item whose stock is not tracked returns 422 unlimited_inventory).
  • Where total_inventory is not available (StockUpdateRequest in /openapi.json has no total_inventory, so sending it alone returns 400; or total_inventory returns 503 capability_not_enabled, meaning it is not enabled yet — nothing is written in either case), send adjustment = 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 the reserved_inventory key is absent, or for items whose inventory is null. 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. If adjustment fails with 422 negative_inventory, do not drop the delta: import orders, read the item again, recompute, and send with a new Idempotency-Key. Only if X is still lower than reserved_inventory after re-reading, write inventory: 0, and always reconcile again about 10 minutes later.
  • Identify the purchased variant by variant on the line item. The line item's sku is the SKU currently set on the parent item, so it is the same for every variant of that item. When variant.id is null (the variant was deleted, its SKU or name changed, several variants share the SKU, and so on), match on variant.sku and variant.name. When variant.sku is null (no SKU was set at purchase time), match on variant.name, and hand it to a person if that does not identify a single variant.
  • Cancelled orders are void and closed. Neither returns stock automatically.
  • init means 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 returns init orders 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 is init, you will miss it.
  • Origin of image fetches (allowlist these if your image host restricts access):
ItemValue
User-Agentatouch-api/1.0 (+https://developers.atouch.jp)
Acceptimage/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.