Alter Product Public API連携

Public API は、ストアフロント、コマースバックエンド、WordPress/WooCommerce プラグイン、外部の生産ワークフローとのサーバー間連携向けに設計されています。

認証とベース URL

https://alterproduct.com/public-api/v1

EC 設定パネルで API 認証情報を作成してください。Access Token は一度しか表示されないため、すぐにバックエンドのシークレットストレージに保存してください。

Access Key と Access Token はサーバー上に保管してください。認証が必要なエンドポイントでは、Origin または Referer ヘッダーを含むブラウザーからの呼び出しは拒否されます。

認証情報にはスコープを設定できます。GET /auth/check を使用して、有効なストアフロント、プランの機能、認証情報に対して返されるスコープを確認してください。

x-alter-access-key: YOUR_API_KEY
x-alter-access-token: YOUR_API_TOKEN
パラメータ必須詳細
x-alter-access-keyはい公開される認証情報の識別子。
x-alter-access-tokenはいアクセスキーと対になるシークレットトークン。
x-alter-client-fingerprintいいえ埋め込みセッションのレート制限に使用する、固定のフィンガープリント(任意)。
AuthorizationランタイムのみPOST /embed/session で返される Bearer トークン。/runtime/bootstrap で使用します。

接続テスト

本番環境の連携で同期や埋め込み機能を有効にする前に、認証確認エンドポイントを使用してください。

GET https://alterproduct.com/public-api/v1/auth/check

リクエスト例(fetch)

const response = await fetch('https://alterproduct.com/public-api/v1/auth/check', {
  method: 'GET',
  headers: {
    'x-alter-access-key': process.env.ALTER_ACCESS_KEY,
    'x-alter-access-token': process.env.ALTER_ACCESS_TOKEN
  }
});

const payload = await response.json();

if (!response.ok) {
  throw new Error(payload?.code || payload?.error || `Alter API ${response.status}`);
}

console.log(payload);

レスポンス例

{
  "ok": true,
  "message": "success",
  "storefrontId": 12,
  "userOwnerId": 34,
  "credentialId": 56,
  "scopes": ["orders:read", "orders:write", "products:read"],
  "plan": {
    "requiredPlan": "Business",
    "currentPlanName": "Business",
    "eligible": true,
    "runtimeFlags": {
      "viewer": true,
      "configurator": true,
      "customizer": true
    },
    "limits": {
      "activeRuntimeBindingsLimit": 100,
      "monthlyReassignmentLimit": 1000,
      "monthlyEmbedTokenLimit": 50000
    }
  }
}

以下のヘルパーは、後続の例で使用します。標準の fetch を使用しており、Node.js 18+ または fetch を提供する任意のサーバーランタイムで実行できます。

const ALTER_API_BASE = 'https://alterproduct.com/public-api/v1';

const authHeaders = {
  'x-alter-access-key': process.env.ALTER_ACCESS_KEY,
  'x-alter-access-token': process.env.ALTER_ACCESS_TOKEN
};

async function alterFetch(path, options = {}) {
  const response = await fetch(`${ALTER_API_BASE}${path}`, {
    ...options,
    headers: {
      ...authHeaders,
      ...(options.body ? { 'Content-Type': 'application/json' } : {}),
      ...options.headers
    }
  });

  const payload = await response.json().catch(() => null);

  if (!response.ok) {
    throw new Error(payload?.code || payload?.error || `Alter API ${response.status}`);
  }

  return payload;
}

エンドポイント一覧

以下の表は、backend-public-api/app.js に登録された公開ルートに対応しています。パスには、外部連携で使用する公開プロキシのプレフィックスが含まれています。

メソッドエンドポイント説明アクセス
GET/public-api/healthzサービスのヘルスチェック。公開
GET/public-api/v1/auth/check認証情報を検証し、ストアフロント、スコープ、プランの機能を返します。任意の認証済み認証情報
GET/public-api/v1/customer-ordersページ分割と絞り込みに対応した顧客注文の一覧を返します。orders:read
GET/public-api/v1/customer-orders/:id設定済みの商品項目を含む単一の顧客注文を返します。orders:read
POST/public-api/v1/customer-orders/batchID を指定して最大 100 件の注文を取得します。orders:read
PATCH/public-api/v1/customer-orders/:id/status注文ステータスを更新します。orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantity選択した注文明細の数量を更新します。orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantity/all注文内のすべての項目に同じ数量を設定します。orders:write
DELETE/public-api/v1/customer-orders/:idストアフロントの所有者に属する顧客注文を削除します。orders:write
GET/public-api/v1/products埋め込みの可否とメディア URL を含む、ストアフロントの商品/デザインを返します。products:read
GET/public-api/v1/products/:idストアフロントの商品/デザインを一件返します。products:read
POST/public-api/v1/embed/sessionモデルジェネレーターを含む埋め込みツール向けに、短時間有効なJWTを発行します。embed:session:create
GET/public-api/v1/runtime/bootstrap埋め込み JWT からランタイムのコンテキストを解決します。Bearer 埋め込みトークン
GET/public-api/v1/assets指定した種類のアセットカタログ項目を一覧表示します。任意の認証済み認証情報
GET/public-api/v1/assets/:type/:assetIdダウンロード可能なファイルの役割を含むアセットマニフェストを返します。任意の認証済み認証情報
GET/public-api/v1/assets/:type/:assetId/files/:role役割を指定してアセットファイルをダウンロードします。任意の認証済み認証情報
GET/public-api/v1/design-importsAlter でホストされているインポート可能なデザインを一覧表示します。認証済み認証情報、Business プランが必要
GET/public-api/v1/design-imports/:idデザインのインポートペイロードとファイルの記述情報を返します。認証済み認証情報、Business プランが必要
GET/public-api/v1/design-imports/:id/files/:fileIdデザインのインポート記述情報からファイルをダウンロードします。認証済み認証情報、Business プランが必要
GET/public-api/v1/file/public/products/:productId/:size商品の公開プレビューを返します。サイズには small.png、medium.png、big.png のいずれかを指定してください。公開
GET/public-api/v1/file/protected/:keyストレージキーを指定して保護されたファイルを取得します。署名付き URL または files:read
GET/public-api/v1/fonts利用可能なすべてのフォントを返します。公開
GET/public-api/v1/currenciesすべての通貨を返します。公開
POST/public-api/v1/runtime-bindings/sync-from-wordpressWordPress の商品マッピングからランタイムバインディングを作成または更新します。任意の認証済み認証情報
PATCH/public-api/v1/runtime-bindings/:idランタイムバインディングを部分更新します。任意の認証済み認証情報
POST/public-api/v1/runtime-bindings/:id/activateランタイムバインディングを有効にします。任意の認証済み認証情報
POST/public-api/v1/runtime-bindings/:id/deactivateランタイムバインディングを無効にします。任意の認証済み認証情報
POST/public-api/v1/wp-connect/exchangeWordPress の自動接続用引き継ぎコードを API 認証情報と交換します。使い捨ての引き継ぎコード
GET/public-api/v1/model-generator/catalog表示可能なジェネレーター製品、構成、テンプレートのリビジョンを一覧表示します。embed:session:create
GET/public-api/v1/model-generator/modelsインポート対象のジェネレーターソースを特定のリビジョンに固定した記述子付きでモデルを一覧表示します。embed:session:create
GET/public-api/v1/model-generator/designer-catalogDesignerで使用するジェネレーターモデルのカタログを返します。embed:session:create
GET/public-api/v1/model-generator/projects所有者のジェネレータープロジェクトと、全ユーザーに公開されたプロジェクトを一覧表示します。embed:session:create
GET/public-api/v1/model-generator/projects/:projectIdプロジェクトの最新または指定リビジョン、テンプレート、ファイルマニフェストを返します。embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/revisions/:revisionプロジェクトの最新または指定リビジョン、テンプレート、ファイルマニフェストを返します。embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/artifacts/:artifactIdプロジェクトへのアクセスを確認してから成果物をダウンロードします。embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/template選択した構成リビジョンに対応する、アクセス可能なテンプレート文書を返します。embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/import依存ファイルを含むテンプレートのインポートパッケージを返します。embed:session:create
GET/public-api/v1/model-generator/mannequins両方のマネキンと、それぞれのアセット記述子を返します。embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assetsインポート可能なファイル付きで、テクスチャまたは背景ライブラリのアセットを一覧表示します。embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assets/:assetId単一のテクスチャまたは背景アセットを、そのインポート可能なファイルとともに返します。embed:session:create
GET/public-api/v1/model-generator/public-files/:key許可されたジェネレーターの依存ファイルをダウンロードします。embed:session:create

顧客注文

顧客注文エンドポイントでは、外部ストアから設定済みの明細を読み取り、数量を更新し、注文の履行ステータスを進め、放棄された注文を削除できます。

パラメータ必須詳細
nameいいえデザイン名と数値の注文 ID を検索します。
category_idいいえ商品カテゴリ ID で絞り込みます。
order_statusいいえ指定可能な注文ステータスのいずれか。
offsetいいえデフォルトは 0。>= 0 である必要があります。
limitいいえこのコントローラーのデフォルトは 9、最大は 50 です。
order_byいいえid、created_at、design_name のいずれか。
directionいいえASC または DESC。

リクエスト例(fetch)

const params = new URLSearchParams({
  limit: '20',
  offset: '0',
  order_status: 'shopping_cart',
  order_by: 'created_at',
  direction: 'DESC'
});

const orders = await alterFetch(`/customer-orders?${params.toString()}`);

const order = await alterFetch('/customer-orders/123');

const batch = await alterFetch('/customer-orders/batch', {
  method: 'POST',
  body: JSON.stringify({
    customerOrderIds: [123, 124, 125]
  })
});

指定可能な値

ステータス説明
shopping_cartカートの処理中です。顧客は引き続き設定を編集できます。
editable顧客は引き続き注文を編集できます。
paid注文は支払い済みで、履行を開始できる状態です。
processing注文の履行処理中です。
completed注文の履行が完了しています。
cancelled注文はキャンセルされました。

リクエスト例(fetch)

await alterFetch('/customer-orders/123/status', {
  method: 'PATCH',
  body: JSON.stringify({
    status: 'processing'
  })
});

await alterFetch('/customer-orders/123/quantity', {
  method: 'PATCH',
  body: JSON.stringify({
    items: [
      { orderDetailId: 987, quantity: 3 }
    ]
  })
});

await alterFetch('/customer-orders/123/quantity/all', {
  method: 'PATCH',
  body: JSON.stringify({
    quantity: 2
  })
});

await alterFetch('/customer-orders/123', {
  method: 'DELETE'
});

レスポンス例

{
  "order": {
    "id": 123,
    "customizerId": 381,
    "orderStatus": "shopping_cart",
    "createdAt": "2026-05-28T10:15:00.000Z",
    "customizerOrderURL": "https://alterproduct.com/app/customizer/381/123",
    "productItems": [
      {
        "id": 987,
        "model3d": { "id": 381 },
        "size": {
          "id": 395,
          "name": { "pl": "M", "en": "M" },
          "measureSize": null
        },
        "material": {
          "id": 2,
          "name": { "pl": "Bawełna", "en": "Cotton" }
        },
        "printType": {
          "id": 1,
          "name": { "pl": "DTG", "en": "DTG" }
        },
        "color": {
          "id": 418,
          "name": { "pl": "Domyślny", "en": "Default" },
          "hex": "#ffffff"
        },
        "variant": {
          "id": 531,
          "metadata": null,
          "stockQuantity": 25
        },
        "unitPrice": { "value": 12.5, "currency": "EUR" },
        "totalPrice": { "value": 37.5, "currency": "EUR" },
        "quantity": 3
      }
    ],
    "customizerName": "Men's T-Shirt",
    "productGroup": {
      "id": 4,
      "name": { "pl": "Koszulka", "en": "T-Shirt" }
    },
    "totalPrice": { "value": 37.5, "currency": "EUR" }
  }
}

ストアフロントの商品

商品エンドポイントは、Viewer、Configurator、Customizer として埋め込み可能なストアフロントのデザインを返します。

パラメータ必須詳細
nameいいえ商品/デザイン名を検索します。
customizerいいえtrue または false。
offsetいいえデフォルトは 0。>= 0 である必要があります。
limitいいえデフォルトは 9、最大は 50 です。
order_byいいえid、name、created_at のいずれか。
directionいいえASC または DESC。

リクエスト例(fetch)

const params = new URLSearchParams({
  limit: '20',
  offset: '0',
  name: 't-shirt',
  customizer: 'true',
  order_by: 'created_at',
  direction: 'DESC'
});

const products = await alterFetch(`/products?${params.toString()}`);
const product = await alterFetch('/products/381');

レスポンス例

{
  "products": {
    "items": [
      {
        "id": 381,
        "name": "Men's T-Shirt",
        "createdAt": "2026-01-03T23:55:05.000Z",
        "productId": 4,
        "media": {
          "img": {
            "big": "https://alterproduct.com/public-api/v1/file/public/products/4/big.png",
            "medium": "https://alterproduct.com/public-api/v1/file/public/products/4/medium.png",
            "small": "https://alterproduct.com/public-api/v1/file/public/products/4/small.png"
          },
          "mockups": []
        },
        "storefrontProduct": {
          "id": 89,
          "idUserDesign": 381,
          "shareAccess": "public",
          "isCustomizer": 1
        },
        "runtimeBindings": [
          {
            "id": 42,
            "runtimeType": "customizer",
            "status": "active",
            "externalProductId": "wc_123"
          }
        ],
        "embeddable": {
          "viewer": true,
          "configurator": true,
          "customizer": true
        }
      }
    ],
    "total": 1
  }
}

埋め込みセッションとランタイムの初期化

サーバーで有効期間の短い埋め込みトークンを作成し、iframe/ランタイムに渡した後、ランタイムから Bearer トークンを使用して bootstrap を呼び出します。

パラメータ必須詳細
runtimeBindingId推奨有効なランタイムバインディングの優先識別子。
toolruntimeBindingId がない場合は必須designer | viewer | configurator | customizer | model-generator
toolIdtool: model-generatorローカルのジェネレータープロジェクトの正の数値IDです。UUIDやWooCommerceの商品IDではありません。
originはい埋め込みが表示されるオリジン。例:https://yourstore.com.
designId識別子をいずれか指定Alter Product のデザイン ID。orderId と同時に指定しないでください。
orderId識別子をいずれか指定Customizer の注文 ID。customizer のみで有効です。
cartKey + cartModeいいえCustomizer 専用のカートコンテキスト。cartMode は view または edit です。

リクエスト例(fetch)

const session = await alterFetch('/embed/session', {
  method: 'POST',
  headers: {
    'x-alter-client-fingerprint': '9f1b7a5e4b3c2d1f9f1b7a5e4b3c2d1f'
  },
  body: JSON.stringify({
    runtimeBindingId: 42,
    origin: 'https://yourstore.com'
  })
});

const bootstrapResponse = await fetch('https://alterproduct.com/public-api/v1/runtime/bootstrap', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${session.token}`
  }
});

const bootstrap = await bootstrapResponse.json();
console.log({ session, bootstrap });

注意事項

await alterFetch('/embed/session', {
  method: 'POST',
  body: JSON.stringify({
    tool: 'customizer',
    origin: 'https://yourstore.com',
    orderId: 123
  })
});

await alterFetch('/embed/session', {
  method: 'POST',
  body: JSON.stringify({
    tool: 'viewer',
    origin: 'https://yourstore.com',
    designId: 381
  })
});

レスポンス例

{
  "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ...",
  "expiresIn": 900,
  "kid": "1",
  "mode": "design",
  "runtimeBindingId": 42,
  "runtimeType": "customizer"
}

Runtime bootstrap

{
  "runtimeBindingId": 42,
  "designId": 381,
  "productId": "wc_123",
  "runtimeType": "customizer",
  "storageMode": "wordpress_local",
  "manifestUrl": "https://yourstore.com/wp-content/uploads/alter/381/manifest.json",
  "assetBaseUrl": "https://yourstore.com/wp-content/uploads/alter/381/",
  "manifestHash": "a3b1...",
  "planCapabilities": {
    "viewer": true,
    "configurator": true,
    "customizer": true
  },
  "cartKey": null,
  "cartMode": null,
  "orderId": null
}

3Dモデルジェネレーター

ジェネレーターのインポートエンドポイントは、サーバー間の読み取り専用リクエストに対応します。標準のAPIヘッダー、embed:session:create権限、有効なプランが必要です。インポートの認可ではエディターセッションは発行されず、その月間利用枠も消費しません。エディターを開くときは、ほかの埋め込みツールと共通のmonthlyEmbedTokenLimitカウンターを使用します。

ジェネレーター付きモデルの検索とインポート

/model-generator/modelsを使用して、利用可能なジェネレーター付きモデルを取得します。generator記述子はprojectId、revision、configurationId、templateRevision、productId、productModel3dIdを固定します。そのimportPathから、指定されたソースリビジョンを正確に取得してください。製品アセットのマニフェストには、generatorsと各モデルのgenerator記述子も含まれます。テンプレートは構成とリビジョンを指定して個別にインポートできます。

カタログのフィルター

エンドポイント詳細
/model-generator/modelsモデル一覧:nameまたはq、categoryId、scope(all、own、global)、limit(1–50)、offset。
/model-generator/catalogテンプレートカタログ:generatorType、productId、audience、q、templateKey、configurationId、limit、offset。
/model-generator/projectsプロジェクト一覧:configurationId、q、scope(all、own、global)、limit、offset。公開プロキシではscopeのデフォルト値はallです。
/model-generator/image-libraries/:kind/assetsテクスチャ・背景ライブラリ:kindはtextureまたはbackgroundです。q、category、mapTypeで利用可能なアセットを絞り込みます。

プロジェクトのインポートにはdocument、revision、template、filesマニフェストが含まれます。各ファイルには/v1/model-generator/配下のpathが指定されます。Alter Productからダウンロードするときは、先頭に/public-apiを付けます。必要なファイルを自分のストレージにコピーし、ソース参照をローカル参照に置き換えてください。マネキンとテクスチャライブラリは、それぞれのカタログエンドポイントからインポートします。public-filesでは許可されたアセットパスのみを使用でき、テンプレートは構成・リビジョンのアクセス確認に合格する必要があります。

リクエスト例(fetch)

// Server-side: uses the alterFetch helper and authHeaders defined above.
const catalog = await alterFetch('/model-generator/models?' + new URLSearchParams({
  scope: 'all', limit: '24', offset: '0'
}));

const selected = catalog.items[0];
if (!selected?.generator) throw new Error('Select an available generator model');

const importPath = selected.generator.importPath;
if (!importPath.startsWith('/v1/model-generator/projects/')) {
  throw new Error('Invalid generator import path');
}
const bundle = await alterFetch(importPath.slice('/v1'.length));

for (const file of bundle.files) {
  if (!file.path.startsWith('/v1/model-generator/')) {
    throw new Error('Invalid generator file path');
  }
  const response = await fetch('https://alterproduct.com/public-api' + file.path, {
    headers: authHeaders,
    redirect: 'error'
  });
  if (!response.ok) throw new Error(`File download failed: ${response.status}`);
  const bytes = new Uint8Array(await response.arrayBuffer());
  // Persist bytes in your local storage; record the mapping from
  // file.sourceHref / file.href to the resulting local file reference.
}
// Persist bundle.document, bundle.template and revision metadata locally.
// Import the related product asset and its textures/mockups as needed:
const product = await alterFetch('/assets/products/' + selected.generator.productId);
const mannequins = await alterFetch('/model-generator/mannequins');
console.log({ product, mannequins });

エディターセッションとローカル保存

エディターセッションは、tool: model-generator、ローカルのジェネレータープロジェクトを識別する正の数値toolId、および許可されたストアのoriginを指定して作成します。toolIdはプロジェクトのUUIDやWooCommerceの製品IDではありません。このツールではdesignId、orderId、runtimeBindingId、カートのフィールドを渡さないでください。ジェネレータープロジェクトのUUIDは別の識別子です。返されたtokenをiframeのハンドシェイクで渡します。ランタイムのブートストラップは、storageMode: wordpress_localを含むジェネレーターのコンテキストを返します。

// Server-side, after authorizing the merchant's access to this local project.
const localProjectId = 42; // Local generator project ID, not its UUID or WC product ID.
const session = await alterFetch('/embed/session', {
  method: 'POST',
  body: JSON.stringify({
    tool: 'model-generator',
    toolId: localProjectId,
    origin: 'https://yourstore.com'
  })
});

// The iframe receives session.token through ALTER_CUSTOMIZER_SESSION_READY.
// Do not put API credentials or the token in the iframe URL.
const bootstrapResponse = await fetch('https://alterproduct.com/public-api/v1/runtime/bootstrap', {
  headers: { Authorization: `Bearer ${session.token}` }
});
if (!bootstrapResponse.ok) throw new Error('Generator bootstrap failed');
const context = await bootstrapResponse.json();
console.log(context);

レスポンス例

{
  "runtimeBindingId": null,
  "designId": null,
  "productId": 42,
  "toolId": 42,
  "runtimeType": "model-generator",
  "storageMode": "wordpress_local",
  "parentOrigin": "https://yourstore.com"
}
// Host page: WordPress returns a numeric toolId and a UUID in id.
const url = new URL('https://alterproduct.com/app/model-generator');
url.search = new URLSearchParams({
  embedded: '1',
  lng: 'en',
  parentOrigin: window.location.origin,
  toolId: String(localProject.toolId),
  serverProjectId: localProject.id
}).toString();
// Optional: serverProjectRevision pins an existing saved revision.
iframe.src = url.toString();
// Install the authenticated handshake and storage bridge described below.
// Setting iframe.src alone does not authorize the editor or provide storage.

WordPressブリッジで使用するiframeメッセージ

WordPressプラグインがストレージブリッジを提供し、管理者またはWooCommerceマネージャーの権限を確認します。iframeのorigin、送信元ウィンドウ、nonce、リクエストID、許可されたプロジェクトパスを検証します。ローカルの読み取りと書き込みは、ブリッジから/wp-json/alter-wc/v1/model-generatorへ送信されます。API認証情報はサーバー上に保持されます。独自の統合では、同等の認証付きストレージ処理を実装する必要があります。公開ジェネレーターAPIはプロジェクトをAlter Productに保存しません。

説明
ALTER_CHILD_HELLO / ALTER_PARENT_ACK子フレームがnonce付きでハンドシェイクを開始し、親ページが同じnonceを確認します。
ALTER_CUSTOMIZER_INIT_SESSION / ALTER_CUSTOMIZER_SESSION_READY子フレームがmodel-generatorの編集セッションを要求し、親ページが認可済みトークンを返します。
ALTER_MODEL_GENERATOR_REQUEST子フレームがrequestId、nonce、およびmethod、path、data、responseTypeを含むrequestを送信します。
ALTER_MODEL_GENERATOR_RESPONSE親ページは同じrequestIdとnonceに加え、status、data、headers、および発生したerrorを返します。
// Messages after ALTER_CHILD_HELLO / ALTER_PARENT_ACK agree on the nonce.
// Iframe -> parent:
const sessionRequest = {
  type: 'ALTER_CUSTOMIZER_INIT_SESSION',
  nonce: handshakeNonce,
  payload: {
    tool: 'model-generator', alterProductId: localProject.toolId, mode: 'edit'
  }
};

// Parent -> iframe, after the server authorizes the merchant and issues a token:
const sessionReady = {
  type: 'ALTER_CUSTOMIZER_SESSION_READY',
  nonce: handshakeNonce,
  token: session.token,
  tool: 'model-generator',
  cartKey: `model-generator:${localProject.id}`,
  mode: 'edit',
  localSession: false,
  adminSession: true
};
// Send only to the validated iframe's exact origin and source window.
// An authorized token and successful bootstrap are still required.

保存時にはexpectedRevision、templateRevision、document、成果物への参照を渡します。保存によって変更不可のリビジョンが作成され、expectedRevisionが古い場合はHTTP 409が返されます。WordPressはメタデータをデータベースに、ファイルをuploadsディレクトリに保存します。JSONはコンパクト化され、サイズが小さくなる場合にgzipで圧縮されます。

// Example message from the iframe; savedSnapshot and artifact IDs come
// from the generator. The host checks origin/source/nonce/project permissions.
const message = {
  type: 'ALTER_MODEL_GENERATOR_REQUEST',
  requestId: crypto.randomUUID(),
  nonce: handshakeNonce,
  request: {
    method: 'POST',
    path: `/pattern-generator/projects/${projectUuid}/revisions`,
    data: {
      expectedRevision: loadedRevision,
      name: projectName,
      templateRevision,
      document: savedSnapshot,
      references: { artifactIds: savedArtifactIds }
    },
    responseType: 'json'
  }
};

「保存済みモデルをデザインで使用」を実行すると、保存済みリビジョン全体が関連付けられたデザインに公開されます。購入者は、通常の製品連携とサブスクリプション確認の下で、既存のCustomizer、Configurator、Viewerからそのモデルを使用します。ジェネレーターのエディターは販売者向けツールです。注文リンクは保存済みのプロジェクトとリビジョンを保持するため、後から編集しても過去の注文が意図せず変更されることはありません。

アセットカタログ

アセットカタログは、商品のソースアセット、背景、環境、グラフィックライブラリの項目、デザインテンプレート、モックアップ用アセットを提供します。一覧エンドポイントは軽量な記述情報を返し、詳細エンドポイントにはファイルマニフェストが含まれます。

説明
products基本の商品アセット、プレビュー、3D モデル、素材とテクスチャの記述情報。
backgroundsViewer の静止背景。
environments環境マップとプレビュー画像。
image_libraryストアフロント専用のグラフィックを含む、グラフィックライブラリのアセット。
design_templatesデザインテンプレートのプレビューとレイヤーファイルへの参照。product_id による絞り込みに対応しています。
mockupsモックアップジェネレーターのアセット、背景、オーバーレイマップ。product_id による絞り込みに対応しています。

リクエスト例(fetch)

const assets = await alterFetch('/assets?' + new URLSearchParams({
  type: 'products',
  limit: '20',
  offset: '0',
  search: 'mug'
}));

const details = await alterFetch('/assets/products/4');

const fileResponse = await fetch(
  'https://alterproduct.com/public-api/v1/assets/products/4/files/preview_medium',
  {
    headers: authHeaders
  }
);

const fileBlob = await fileResponse.blob();

レスポンス例

{
  "type": "products",
  "items": [
    {
      "assetType": "products",
      "assetId": "4",
      "title": "Mug 450ml",
      "slug": "product-4",
      "description": "Base product 4",
      "primaryRole": "preview_big",
      "fileCount": 8,
      "remoteVersion": "1.0",
      "thumbnail": {
        "role": "preview_small",
        "fileName": "product-4-preview-small.png",
        "mime": "image/png",
        "downloadPath": "/v1/assets/products/4/files/preview_small"
      },
      "metadata": {
        "productCategoryId": 2,
        "productModelCount": 1,
        "isDedicated": false
      }
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}

デザインのインポート

デザインのインポート機能では、外部の生産・移行フロー向けに、Alter でホストされているデザインとそのファイルを取得できます。Business プランの利用資格は API で確認されます。

パラメータ必須詳細
searchいいえデザインのタイトルまたは ID を検索します。
offsetいいえデフォルトは 0 です。
limitいいえデフォルトは 20、最大は 100 です。

リクエスト例(fetch)

const imports = await alterFetch('/design-imports?' + new URLSearchParams({
  limit: '20',
  offset: '0',
  search: 'mug'
}));

const details = await alterFetch('/design-imports/381');

const fileId = details.files[0].id;
const fileResponse = await fetch(
  `https://alterproduct.com/public-api/v1/design-imports/381/files/${fileId}`,
  {
    headers: authHeaders
  }
);

const fileBlob = await fileResponse.blob();

レスポンス例

{
  "eligible": true,
  "requiredPlan": "Business",
  "currentPlanName": "Business",
  "designs": [
    {
      "id": 381,
      "title": "Men's T-Shirt",
      "createdAt": "2026-01-03T23:55:05.000Z",
      "sourceStorefrontId": 12,
      "productId": 4,
      "productName": {
        "pl": "Koszulka",
        "en": "T-Shirt"
      },
      "storageMode": "alter",
      "runtimeStatus": {
        "designer": true,
        "viewer": true,
        "configurator": true,
        "customizer": true
      },
      "thumbnail": {
        "kind": "design-mockup",
        "fileId": "7df7...",
        "downloadPath": "/v1/design-imports/381/files/7df7..."
      }
    }
  ],
  "total": 1
}

ファイル、フォント、通貨

公開プレビューファイルはブラウザーで利用できます。保護されたファイルには、署名付き URL または files:read スコープを持つ API 認証情報が必要です。フォントと通貨は公開の読み取りエンドポイントです。

エンドポイントアクセス詳細
/file/public/products/:productId/small.png公開小サイズの商品プレビュー。
/file/public/products/:productId/medium.png公開中サイズの商品プレビュー。
/file/public/products/:productId/big.png公開大サイズの商品プレビュー。
/file/protected/:key署名付き URL または files:read保護されたオブジェクトストレージのファイル。
/fonts公開フォントレコードの配列。
/currencies公開通貨レコードの配列。

リクエスト例(fetch)

const publicPreview = await fetch(
  'https://alterproduct.com/public-api/v1/file/public/products/4/medium.png'
);

const protectedFile = await fetch(
  'https://alterproduct.com/public-api/v1/file/protected/user_34/381/design/mockup-large.webp',
  {
    headers: authHeaders
  }
);

const fonts = await fetch('https://alterproduct.com/public-api/v1/fonts').then((res) => res.json());
const currencies = await fetch('https://alterproduct.com/public-api/v1/currencies').then((res) => res.json());

レスポンス例

[
  {
    "id": 1,
    "family": "Inter",
    "source": "google",
    "category": "sans-serif",
    "variants": ["regular", "600", "700"],
    "subsets": ["latin"],
    "version": "v19",
    "menu": "Inter",
    "files": {
      "regular": "https://..."
    }
  }
]
[
  {
    "id": 1,
    "code": "EUR",
    "name": "Euro",
    "symbol": "€",
    "decimalPlaces": 2
  }
]

ランタイムバインディング

ランタイムバインディングは、外部コマースの商品を Alter Product のデザインとランタイムの種類に関連付けます。主に WordPress/WooCommerce 連携や高度なストアフロントのバックエンドで使用します。

パラメータ必須詳細
designIdいいえストアフロントが所有する Alter Product のデザイン ID。
externalProductId同期時は必須外部の商品 ID。例:WooCommerce の商品 ID。
runtimeType同期時は必須viewer、configurator、customizer のいずれか。
statusいいえdraft、active、inactive、archived、legacy_active のいずれか。
legacyStorefrontProductIdいいえ旧形式のマッピング ID(任意)。
legacyBindingMetaいいえ任意の JSON メタデータ。例:manifestHash。

リクエスト例(fetch)

await alterFetch('/runtime-bindings/sync-from-wordpress', {
  method: 'POST',
  body: JSON.stringify({
    bindings: [
      {
        externalProductId: 'wc_123',
        runtimeType: 'customizer',
        status: 'active',
        designId: 381,
        legacyBindingMeta: {
          manifestHash: 'a3b1...'
        }
      }
    ]
  })
});

await alterFetch('/runtime-bindings/42', {
  method: 'PATCH',
  body: JSON.stringify({
    status: 'inactive'
  })
});

await alterFetch('/runtime-bindings/42/activate', { method: 'POST' });
await alterFetch('/runtime-bindings/42/deactivate', { method: 'POST' });

wordpress_local

await alterFetch('/runtime-bindings/sync-from-wordpress', {
  method: 'POST',
  body: JSON.stringify({
    bindings: [
      {
        externalProductId: 'wc_123',
        runtimeType: 'viewer',
        status: 'active',
        externalDesign: {
          externalDesignKey: 'wp-design-381',
          productId: 4,
          title: 'WooCommerce local design',
          manifestUrl: 'https://yourstore.com/wp-content/uploads/alter/381/manifest.json',
          assetBaseUrl: 'https://yourstore.com/wp-content/uploads/alter/381/',
          manifestHash: 'a3b1...',
          sourceMeta: {
            pluginVersion: '1.2.0'
          }
        }
      }
    ]
  })
});

レスポンス例

{
  "message": "runtimeBinding.syncCompleted",
  "runtimeBindings": [
    {
      "id": 42,
      "designId": 381,
      "externalProductId": "wc_123",
      "runtimeType": "customizer",
      "status": "active"
    }
  ]
}

WordPress 接続情報の交換

WordPress 接続情報の交換エンドポイントは、使い捨ての引き継ぎコードを使用し、プラグインに API 認証情報を返します。汎用的な認証情報作成エンドポイントではありません。

リクエスト例(fetch)

const response = await fetch('https://alterproduct.com/public-api/v1/wp-connect/exchange', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    code: 'ONE_TIME_HANDOFF_CODE',
    storeUrl: 'https://yourstore.com/',
    siteOrigin: 'https://yourstore.com',
    codeVerifier: 'PKCE_CODE_VERIFIER_32_TO_128_CHARS'
  })
});

const credentials = await response.json();

レスポンス例

{
  "message": "wpConnect.exchange.ok",
  "accessKey": "generated-access-key",
  "accessToken": "generated-access-token",
  "storefrontId": 12
}

エラーとレート制限

コントローラーのエラーの多くは、code レスポンスに正規化されます。認証ミドルウェアとレートリミッターでは、代わりに error レスポンスが返される場合があります。

// Controller error
{
  "code": "assetCatalog.invalidType"
}

// Auth middleware or rate limit
{
  "error": "Unauthorized"
}

{
  "error": "Too Many Requests"
}
上限期間
全体600 リクエスト60 秒
GET /auth/check60 リクエスト60 秒
注文の読み取り/商品の読み取り300 リクエスト60 秒
注文の書き込み/埋め込みセッション/ランタイムバインディング120 リクエスト60 秒
アセット/デザインインポートの読み取り180 リクエスト60 秒
フォント300 リクエスト60 秒
WP 接続情報の交換30 リクエスト60 秒
GET /model-generator/*600 リクエスト60 秒