Alter Product Public API-integratie

De Public API is bedoeld voor server-naar-serverintegraties met winkels, commercebackends, WordPress/WooCommerce-plug-ins en externe productieworkflows.

Authenticatie en basis-URL

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

Maak API-inloggegevens aan in het paneel met e-commerce-instellingen. De Access Token wordt één keer getoond, dus sla deze direct op in de beveiligde opslag van je backend.

Bewaar de Access Key en Access Token op je server. Geauthenticeerde endpoints weigeren browserverzoeken met Origin- of Referer-headers.

Inloggegevens kunnen beperkte machtigingen hebben. Gebruik GET /auth/check om de actieve winkel, planmogelijkheden en machtigingen van de inloggegevens te controleren.

x-alter-access-key: YOUR_API_KEY
x-alter-access-token: YOUR_API_TOKEN
ParameterVerplichtDetails
x-alter-access-keyjaOpenbare identificatie van de inloggegevens.
x-alter-access-tokenjaGeheim token dat bij de toegangssleutel hoort.
x-alter-client-fingerprintneeOptionele vaste vingerafdruk voor de begrenzing van embedsessieverzoeken.
Authorizationalleen runtimeBearer-token van POST /embed/session, gebruikt door /runtime/bootstrap.

Verbindingstest

Gebruik het authenticatiecontrole-endpoint voordat je synchronisatie of integratiefuncties in een liveomgeving inschakelt.

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

Voorbeeldverzoek (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);

Voorbeeldantwoord

{
  "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
    }
  }
}

De onderstaande helper wordt in de overige voorbeelden gebruikt. Deze gebruikt gewone fetch en werkt in Node.js 18+ of elke serverruntime die fetch ondersteunt.

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;
}

Endpointoverzicht

De onderstaande tabel komt overeen met de openbare routes in backend-public-api/app.js. De paden bevatten het openbare proxyvoorvoegsel voor externe integraties.

MethodeEndpointBeschrijvingToegang
GET/public-api/healthzStatuscontrole van de service.openbaar
GET/public-api/v1/auth/checkValideert inloggegevens en retourneert de winkel, machtigingen en planmogelijkheden.alle geauthenticeerde inloggegevens
GET/public-api/v1/customer-ordersRetourneert een gepagineerde en filterbare lijst met klantbestellingen.orders:read
GET/public-api/v1/customer-orders/:idRetourneert één klantbestelling met geconfigureerde productartikelen.orders:read
POST/public-api/v1/customer-orders/batchRetourneert maximaal 100 bestellingen op ID.orders:read
PATCH/public-api/v1/customer-orders/:id/statusWerkt de bestelstatus bij.orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantityWerkt de aantallen van geselecteerde besteldetails bij.orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantity/allStelt één aantal in voor elk artikel in een bestelling.orders:write
DELETE/public-api/v1/customer-orders/:idVerwijdert een klantbestelling die eigendom is van de winkeleigenaar.orders:write
GET/public-api/v1/productsRetourneert winkelproducten/ontwerpen met integratiemogelijkheden en media-URL's.products:read
GET/public-api/v1/products/:idRetourneert één winkelproduct/ontwerp.products:read
POST/public-api/v1/embed/sessionGeeft een kort geldig JWT uit voor ingesloten tools, waaronder de modelgenerator.embed:session:create
GET/public-api/v1/runtime/bootstrapBepaalt de runtimecontext op basis van een embed-JWT.Bearer-embedtoken
GET/public-api/v1/assetsToont assetcatalogusitems van het aangevraagde type.alle geauthenticeerde inloggegevens
GET/public-api/v1/assets/:type/:assetIdRetourneert een assetmanifest met downloadbare bestandsrollen.alle geauthenticeerde inloggegevens
GET/public-api/v1/assets/:type/:assetId/files/:roleDownloadt een assetbestand op basis van de rol.alle geauthenticeerde inloggegevens
GET/public-api/v1/design-importsToont importeerbare ontwerpen uit Alter-opslag.geauthenticeerde inloggegevens, Business-plan vereist
GET/public-api/v1/design-imports/:idRetourneert een ontwerpimportpayload en bestandsbeschrijvingen.geauthenticeerde inloggegevens, Business-plan vereist
GET/public-api/v1/design-imports/:id/files/:fileIdDownloadt een bestand uit een ontwerpimportbeschrijving.geauthenticeerde inloggegevens, Business-plan vereist
GET/public-api/v1/file/public/products/:productId/:sizeRetourneert een openbaar productvoorbeeld. De grootte moet small.png, medium.png of big.png zijn.openbaar
GET/public-api/v1/file/protected/:keyRetourneert een beveiligd bestand op basis van de opslagsleutel.ondertekende URL of files:read
GET/public-api/v1/fontsRetourneert alle beschikbare lettertypen.openbaar
GET/public-api/v1/currenciesRetourneert alle valuta's.openbaar
POST/public-api/v1/runtime-bindings/sync-from-wordpressMaakt of actualiseert runtimekoppelingen op basis van WordPress-productkoppelingen.alle geauthenticeerde inloggegevens
PATCH/public-api/v1/runtime-bindings/:idWerkt een runtimekoppeling gedeeltelijk bij.alle geauthenticeerde inloggegevens
POST/public-api/v1/runtime-bindings/:id/activateActiveert een runtimekoppeling.alle geauthenticeerde inloggegevens
POST/public-api/v1/runtime-bindings/:id/deactivateDeactiveert een runtimekoppeling.alle geauthenticeerde inloggegevens
POST/public-api/v1/wp-connect/exchangeWisselt een overdrachtscode voor automatisch verbinden met WordPress in voor API-inloggegevens.eenmalige overdrachtscode
GET/public-api/v1/model-generator/catalogToont zichtbare generatorproducten, configuraties en sjabloonrevisies.embed:session:create
GET/public-api/v1/model-generator/modelsToont modellen met descriptors die voor import naar specifieke generatorbronrevisies verwijzen.embed:session:create
GET/public-api/v1/model-generator/designer-catalogRetourneert de catalogus met generatormodellen die Designer gebruikt.embed:session:create
GET/public-api/v1/model-generator/projectsToont de generatorprojecten van de eigenaar en wereldwijd beschikbare projecten.embed:session:create
GET/public-api/v1/model-generator/projects/:projectIdRetourneert de nieuwste of geselecteerde projectrevisie, het sjabloon en het bestandsmanifest.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/revisions/:revisionRetourneert de nieuwste of geselecteerde projectrevisie, het sjabloon en het bestandsmanifest.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/artifacts/:artifactIdDownloadt een artefact nadat de toegang tot het bijbehorende project is gecontroleerd.embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/templateRetourneert een toegankelijk sjabloondocument voor de geselecteerde configuratierevisie.embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/importRetourneert het importpakket van het sjabloon met de afhankelijkheidsbestanden.embed:session:create
GET/public-api/v1/model-generator/mannequinsRetourneert beide mannequins en de descriptors van hun bronnen.embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assetsToont assets uit de textuur- of achtergrondbibliotheek met importeerbare bestanden.embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assets/:assetIdRetourneert één textuur- of achtergrondasset met de bijbehorende importeerbare bestanden.embed:session:create
GET/public-api/v1/model-generator/public-files/:keyDownloadt een toegestaan afhankelijkheidsbestand van de generator.embed:session:create

Klantbestellingen

Met klantbestel-endpoints kan een externe winkel geconfigureerde bestelregels lezen, aantallen aanpassen, de afhandelingsstatus wijzigen en verlaten bestellingen verwijderen.

ParameterVerplichtDetails
nameneeZoekt op ontwerpnaam en numeriek bestel-ID.
category_idneeFiltert op productcategorie-ID.
order_statusneeEen van de toegestane bestelstatussen.
offsetneeStandaard 0. Moet >= 0 zijn.
limitneeStandaard 9 voor deze controller, maximaal 50.
order_byneeid, created_at of design_name.
directionneeASC of DESC.

Voorbeeldverzoek (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]
  })
});

Toegestane waarden

StatusBeschrijving
shopping_cartWinkelwagenfase; de klant kan de configuratie nog bewerken.
editableDe bestelling blijft bewerkbaar voor de klant.
paidDe bestelling is betaald en klaar voor afhandeling.
processingDe bestelling wordt afgehandeld.
completedDe bestelling is afgehandeld.
cancelledDe bestelling is geannuleerd.

Voorbeeldverzoek (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'
});

Voorbeeldantwoord

{
  "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" }
  }
}

Winkelproducten

Productendpoints retourneren winkelontwerpen die als Viewer-, Configurator- of Customizer-ervaring kunnen worden geïntegreerd.

ParameterVerplichtDetails
nameneeZoekt op product-/ontwerpnaam.
customizerneetrue of false.
offsetneeStandaard 0. Moet >= 0 zijn.
limitneeStandaard 9, maximaal 50.
order_byneeid, name of created_at.
directionneeASC of DESC.

Voorbeeldverzoek (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');

Voorbeeldantwoord

{
  "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
  }
}

Embedsessies en runtime-initialisatie

Maak op je server een kort geldig embedtoken aan, geef het door aan het iframe/de runtime en laat de runtime vervolgens bootstrap aanroepen met een Bearer-token.

ParameterVerplichtDetails
runtimeBindingIdaanbevolenVoorkeursidentificatie voor actieve runtimekoppelingen.
toolverplicht zonder runtimeBindingIddesigner | viewer | configurator | customizer | model-generator
toolIdtool: model-generatorPositieve numerieke ID van het lokale generatorproject, niet de UUID of de WooCommerce-product-ID.
originjaOrigin waarop de integratie wordt weergegeven, bijvoorbeeld https://yourstore.com.
designIdéén identificatieAlter Product-ontwerp-ID. Niet combineren met orderId.
orderIdéén identificatieCustomizer-bestel-ID. Alleen geldig voor customizer.
cartKey + cartModeneeWinkelwagencontext uitsluitend voor de Customizer. cartMode is view of edit.

Voorbeeldverzoek (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 });

Opmerkingen

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
  })
});

Voorbeeldantwoord

{
  "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-modelgenerator

De importeindpunten van de generator ondersteunen alleen leesverzoeken tussen servers. Ze vereisen de gebruikelijke API-headers, de scope embed:session:create en een actief abonnement. Importautorisatie maakt geen editorsessie aan en verbruikt het maandelijkse quotum daarvoor niet. Het openen van de editor gebruikt dezelfde teller monthlyEmbedTokenLimit als de andere ingesloten tools.

Modellen met generator zoeken en importeren

Gebruik /model-generator/models om beschikbare modellen met een generator op te vragen. De descriptor generator legt projectId, revision, configurationId, templateRevision, productId en productModel3dId vast. Volg de bijbehorende importPath om precies die bronrevisie op te halen. Manifesten van productassets bevatten ook generators en de descriptor generator van elk model. Sjablonen kunnen afzonderlijk worden geïmporteerd op basis van configuratie en revisie.

Catalogusfilters

EndpointDetails
/model-generator/modelsModellijst: name (of q), categoryId, scope (all, own, global), limit (1–50) en offset.
/model-generator/catalogSjablooncatalogus: generatorType, productId, audience, q, templateKey, configurationId, limit en offset.
/model-generator/projectsProjectlijst: configurationId, q, scope (all, own, global), limit en offset. De openbare proxy stelt scope standaard in op all.
/model-generator/image-libraries/:kind/assetsTextuur- en achtergrondbibliotheken: kind is texture of background; q, category en mapType filteren de beschikbare assets.

Een projectimport bevat document, revision, template en een manifest files. Elk bestand levert een path onder /v1/model-generator/; voeg /public-api vóór dit pad toe wanneer je het van Alter Product downloadt. Kopieer de benodigde bestanden naar je eigen opslag en vervang de bronverwijzingen door lokale verwijzingen. Importeer mannequins en textuurbibliotheken via hun cataloguseindpunten; public-files is beperkt tot toegestane bronpaden en sjablonen moeten de toegangscontroles voor hun configuratie en revisie doorlopen.

Voorbeeldverzoek (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 });

Editorsessie en lokale opslag

Maak de editorsessie aan met tool: model-generator, een positieve numerieke toolId die het lokale generatorproject identificeert (niet de UUID ervan of het WooCommerce-product-ID) en de toegestane oorsprong van de winkel. Geef voor deze tool geen designId, orderId, runtimeBindingId of winkelwagenvelden mee. De UUID van het generatorproject is een aparte identificatie. Geef het ontvangen token door via de iframe-handshake; de runtime-bootstrap retourneert de generatorcontext met 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);

Voorbeeldantwoord

{
  "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.

Iframe-berichten van de WordPress-brug

De WordPress-plugin verzorgt de opslagbrug en controleert beheerdersrechten of rechten voor WooCommerce-beheer. De plugin valideert de oorsprong van het iframe, het bronvenster, de nonce, het verzoek-ID en de toegestane projectpaden. De brug stuurt lokale lees- en schrijfverzoeken naar /wp-json/alter-wc/v1/model-generator. API-inloggegevens blijven op de server. Een aangepaste integratie moet gelijkwaardige, geauthenticeerde opslagafhandeling implementeren; de openbare generator-API slaat geen projecten op bij Alter Product.

TypeBeschrijving
ALTER_CHILD_HELLO / ALTER_PARENT_ACKHet iframe start de handshake met een nonce; de bovenliggende pagina bevestigt dezelfde nonce.
ALTER_CUSTOMIZER_INIT_SESSION / ALTER_CUSTOMIZER_SESSION_READYHet iframe vraagt een bewerkingssessie voor model-generator aan; de bovenliggende pagina retourneert het geautoriseerde token.
ALTER_MODEL_GENERATOR_REQUESTHet iframe stuurt requestId, nonce en request met daarin method, path, data en responseType.
ALTER_MODEL_GENERATOR_RESPONSEDe bovenliggende pagina antwoordt met dezelfde requestId en nonce, plus status, data, headers en een eventuele 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.

Bij het opslaan worden expectedRevision, templateRevision, document en artefactverwijzingen meegestuurd. Dit maakt een onveranderlijke revisie aan; een verouderde expectedRevision levert HTTP 409 op. WordPress bewaart metadata in zijn database en bestanden in zijn uploads-map. JSON wordt geminificeerd en met gzip gecomprimeerd wanneer compressie de omvang verkleint.

// 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'
  }
};

Opgeslagen model in ontwerp gebruiken publiceert een volledige opgeslagen revisie naar een gekoppeld productontwerp. Klanten zien deze vervolgens via de bestaande Customizer, Configurator of Viewer, met de gebruikelijke productkoppelingen en abonnementscontroles. De generatoreditor blijft een tool voor de verkoper. Bestellingskoppelingen behouden het opgeslagen project en de revisie, zodat latere bewerkingen eerdere bestellingen niet ongemerkt wijzigen.

Assetcatalogus

De assetcatalogus biedt bronassets van producten, achtergronden, omgevingen, bibliotheekafbeeldingen, ontwerpsjablonen en mockupassets. Lijstendpoints retourneren compacte beschrijvingen; detailendpoints bevatten bestandsmanifesten.

TypeBeschrijving
productsBasisproductassets, voorbeelden, 3D-modellen en beschrijvingen van materialen en texturen.
backgroundsStatische Viewer-achtergronden.
environmentsOmgevingskaarten en voorbeeldafbeeldingen.
image_libraryAssets uit de afbeeldingenbibliotheek, inclusief winkelspecifieke afbeeldingen.
design_templatesVoorbeelden van ontwerpsjablonen en verwijzingen naar laagbestanden. Ondersteunt het filter product_id.
mockupsMockupgeneratorassets, achtergronden en overlaykaarten. Ondersteunt het filter product_id.

Voorbeeldverzoek (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();

Voorbeeldantwoord

{
  "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
}

Ontwerpimports

Ontwerpimports bieden ontwerpen en bestanden uit Alter-opslag aan voor externe productie- of migratieprocessen. De API controleert of het Business-plan dit toestaat.

ParameterVerplichtDetails
searchneeZoekt op ontwerptitel of ID.
offsetneeStandaard 0.
limitneeStandaard 20, maximaal 100.

Voorbeeldverzoek (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();

Voorbeeldantwoord

{
  "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
}

Bestanden, lettertypen en valuta's

Openbare voorbeeldbestanden zijn geschikt voor browsers. Beveiligde bestanden vereisen een ondertekende URL of API-inloggegevens met files:read. Lettertypen en valuta's zijn openbare leesendpoints.

EndpointToegangDetails
/file/public/products/:productId/small.pngopenbaarKlein productvoorbeeld.
/file/public/products/:productId/medium.pngopenbaarMiddelgroot productvoorbeeld.
/file/public/products/:productId/big.pngopenbaarGroot productvoorbeeld.
/file/protected/:keyondertekende URL of files:readBeveiligd bestand in objectopslag.
/fontsopenbaarReeks lettertyperecords.
/currenciesopenbaarReeks valutarecords.

Voorbeeldverzoek (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());

Voorbeeldantwoord

[
  {
    "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
  }
]

Runtimekoppelingen

Runtimekoppelingen verbinden externe e-commerceproducten met Alter Product-ontwerpen en runtimetypen. Ze worden vooral gebruikt voor WordPress/WooCommerce-integraties en geavanceerde winkelbackends.

ParameterVerplichtDetails
designIdneeID van een Alter Product-ontwerp dat eigendom is van de winkel.
externalProductIdja, voor synchronisatieExtern product-ID, bijvoorbeeld een WooCommerce-product-ID.
runtimeTypeja, voor synchronisatieviewer, configurator of customizer.
statusneedraft, active, inactive, archived of legacy_active.
legacyStorefrontProductIdneeOptioneel ID van een oude koppeling.
legacyBindingMetaneeOptionele JSON-metadata, bijvoorbeeld manifestHash.

Voorbeeldverzoek (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'
          }
        }
      }
    ]
  })
});

Voorbeeldantwoord

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

WordPress-verbinding uitwisselen

Het WordPress-uitwisselingsendpoint gebruikt een eenmalige overdrachtscode en retourneert API-inloggegevens aan de plug-in. Het is geen algemeen endpoint voor het aanmaken van inloggegevens.

Voorbeeldverzoek (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();

Voorbeeldantwoord

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

Fouten en verzoeklimieten

De meeste controllerfouten worden omgezet in een code-antwoord. Authenticatiemiddleware en verzoekbegrenzers kunnen in plaats daarvan een error-antwoord geven.

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

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

{
  "error": "Too Many Requests"
}
TypeLimietTijdsvenster
Globaal600 verzoeken60 seconden
GET /auth/check60 verzoeken60 seconden
Bestellingen lezen/producten lezen300 verzoeken60 seconden
Bestellingen schrijven/embedsessies/runtimekoppelingen120 verzoeken60 seconden
Assets/ontwerpimports lezen180 verzoeken60 seconden
Lettertypen300 verzoeken60 seconden
WP-verbinding uitwisselen30 verzoeken60 seconden
GET /model-generator/*600 verzoeken60 seconden