Integration med Alter Product Public API

Public API är utformat för integrationer mellan servrar med butiker, e-handelsbackender, WordPress/WooCommerce-tillägg och externa produktionsflöden.

Autentisering och bas-URL

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

Skapa API-uppgifter i panelen för e-handelsinställningar. Access Token visas bara en gång, så spara den omedelbart i din backends lagring för hemligheter.

Behåll Access Key och Access Token på din server. Autentiserade ändpunkter avvisar webbläsaranrop med Origin- eller Referer-huvuden.

Uppgifter kan ha begränsade behörighetsomfång. Använd GET /auth/check för att kontrollera aktiv butik, planfunktioner och behörighetsomfång för uppgifterna.

x-alter-access-key: YOUR_API_KEY
x-alter-access-token: YOUR_API_TOKEN
ParameterObligatorisktDetaljer
x-alter-access-keyjaOffentlig identifierare för uppgifter.
x-alter-access-tokenjaHemlig token som hör till åtkomstnyckeln.
x-alter-client-fingerprintnejValfritt stabilt fingeravtryck för anropsbegränsning av inbäddningssessioner.
Authorizationendast runtimeBearer-token från POST /embed/session, används av /runtime/bootstrap.

Anslutningstest

Använd autentiseringskontrollens ändpunkt innan du aktiverar synkronisering eller inbäddning i en produktionsintegration.

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

Exempel på begäran (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);

Exempel på svar

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

Hjälpfunktionen nedan används i de återstående exemplen. Den använder vanlig fetch och kan köras i Node.js 18+ eller annan servermiljö med stöd för 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;
}

Ändpunktsöversikt

Tabellen nedan återger de offentliga rutterna i backend-public-api/app.js. Sökvägar visas med det offentliga proxyprefix som används av externa integrationer.

MetodÄndpunktBeskrivningÅtkomst
GET/public-api/healthzHälsokontroll av tjänsten.offentlig
GET/public-api/v1/auth/checkValiderar uppgifter och returnerar butik, behörighetsomfång och planfunktioner.valfria autentiserade uppgifter
GET/public-api/v1/customer-ordersReturnerar en sidindelad och filtrerbar lista över kundbeställningar.orders:read
GET/public-api/v1/customer-orders/:idReturnerar en kundbeställning med konfigurerade produktartiklar.orders:read
POST/public-api/v1/customer-orders/batchReturnerar upp till 100 beställningar efter ID.orders:read
PATCH/public-api/v1/customer-orders/:id/statusUppdaterar orderstatus.orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantityUppdaterar antal för valda orderdetaljer.orders:write
PATCH/public-api/v1/customer-orders/:orderId/quantity/allAnger samma antal för varje artikel i en beställning.orders:write
DELETE/public-api/v1/customer-orders/:idTar bort en kundbeställning som tillhör butiksägaren.orders:write
GET/public-api/v1/productsReturnerar butiksprodukter/designer med inbäddningstillgänglighet och medieadresser.products:read
GET/public-api/v1/products/:idReturnerar en butiksprodukt/design.products:read
POST/public-api/v1/embed/sessionUtfärdar en kortlivad JWT för inbäddade verktyg, inklusive modellgeneratorn.embed:session:create
GET/public-api/v1/runtime/bootstrapTolkar runtimekontext från en inbäddnings-JWT.Bearer-token för inbäddning
GET/public-api/v1/assetsListar resurskatalogobjekt av den begärda typen.valfria autentiserade uppgifter
GET/public-api/v1/assets/:type/:assetIdReturnerar ett resursmanifest med nedladdningsbara filroller.valfria autentiserade uppgifter
GET/public-api/v1/assets/:type/:assetId/files/:roleLaddar ner en resursfil efter roll.valfria autentiserade uppgifter
GET/public-api/v1/design-importsListar importerbara designer som lagras hos Alter.autentiserade uppgifter, Business-plan krävs
GET/public-api/v1/design-imports/:idReturnerar designimportens payload och filbeskrivningar.autentiserade uppgifter, Business-plan krävs
GET/public-api/v1/design-imports/:id/files/:fileIdLaddar ner en fil från ett designimportobjekt.autentiserade uppgifter, Business-plan krävs
GET/public-api/v1/file/public/products/:productId/:sizeReturnerar en offentlig produktförhandsvisning. Storleken måste vara small.png, medium.png eller big.png.offentlig
GET/public-api/v1/file/protected/:keyReturnerar en skyddad fil efter lagringsnyckel.signerad URL eller files:read
GET/public-api/v1/fontsReturnerar alla tillgängliga typsnitt.offentlig
GET/public-api/v1/currenciesReturnerar alla valutor.offentlig
POST/public-api/v1/runtime-bindings/sync-from-wordpressSkapar eller uppdaterar runtimekopplingar från WordPress-produktkopplingar.valfria autentiserade uppgifter
PATCH/public-api/v1/runtime-bindings/:idUppdaterar delar av en runtimekoppling.valfria autentiserade uppgifter
POST/public-api/v1/runtime-bindings/:id/activateAktiverar en runtimekoppling.valfria autentiserade uppgifter
POST/public-api/v1/runtime-bindings/:id/deactivateInaktiverar en runtimekoppling.valfria autentiserade uppgifter
POST/public-api/v1/wp-connect/exchangeByter en överlämningskod för automatisk WordPress-anslutning mot API-uppgifter.engångskod för överlämning
GET/public-api/v1/model-generator/catalogListar synliga generatorprodukter, konfigurationer och mallrevisioner.embed:session:create
GET/public-api/v1/model-generator/modelsListar modeller med låsta beskrivningar av generatorkällan för import.embed:session:create
GET/public-api/v1/model-generator/designer-catalogReturnerar katalogen med generatormodeller som används av Designer.embed:session:create
GET/public-api/v1/model-generator/projectsListar ägarens och globalt tillgängliga generatorprojekt.embed:session:create
GET/public-api/v1/model-generator/projects/:projectIdReturnerar den senaste eller valda projektrevisionen, mallen och filmanifestet.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/revisions/:revisionReturnerar den senaste eller valda projektrevisionen, mallen och filmanifestet.embed:session:create
GET/public-api/v1/model-generator/projects/:projectId/artifacts/:artifactIdLaddar ned en resultatfil efter kontroll av åtkomsten till dess projekt.embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/templateReturnerar ett tillgängligt malldokument för den valda konfigurationsrevisionen.embed:session:create
GET/public-api/v1/model-generator/configurations/:configurationId/revisions/:revision/importReturnerar mallens importpaket med beroendefiler.embed:session:create
GET/public-api/v1/model-generator/mannequinsReturnerar båda mannequinerna och deras resursbeskrivningar.embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assetsListar resurser från textur- eller bakgrundsbiblioteket med filer som kan importeras.embed:session:create
GET/public-api/v1/model-generator/image-libraries/:kind/assets/:assetIdReturnerar en textur- eller bakgrundsresurs med dess importerbara filer.embed:session:create
GET/public-api/v1/model-generator/public-files/:keyLaddar ned en tillåten beroendefil för generatorn.embed:session:create

Kundbeställningar

Kundorderändpunkterna låter en extern butik läsa konfigurerade orderrader, uppdatera antal, flytta beställningar mellan behandlingsstatusar och ta bort övergivna beställningar.

ParameterObligatorisktDetaljer
namenejSöker efter designnamn och numeriskt order-ID.
category_idnejFiltrerar efter produktkategori-ID.
order_statusnejEn av de tillåtna orderstatusarna.
offsetnejStandard 0. Måste vara >= 0.
limitnejStandard 9 för denna controller, högst 50.
order_bynejid, created_at eller design_name.
directionnejASC eller DESC.

Exempel på begäran (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]
  })
});

Tillåtna värden

StatusBeskrivning
shopping_cartKundvagnsflöde; kunden kan fortfarande redigera konfigurationen.
editableBeställningen kan fortfarande redigeras av kunden.
paidBeställningen är betald och klar för behandling.
processingBeställningen behandlas.
completedBeställningen har slutförts.
cancelledBeställningen har avbrutits.

Exempel på begäran (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'
});

Exempel på svar

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

Butiksprodukter

Produktändpunkterna returnerar butiksdesigner som kan bäddas in som Viewer-, Configurator- eller Customizer-upplevelser.

ParameterObligatorisktDetaljer
namenejSöker efter produkt-/designnamn.
customizernejtrue eller false.
offsetnejStandard 0. Måste vara >= 0.
limitnejStandard 9, högst 50.
order_bynejid, name eller created_at.
directionnejASC eller DESC.

Exempel på begäran (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');

Exempel på svar

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

Inbäddningssessioner och runtimeinitiering

Skapa en kortlivad inbäddningstoken på servern, skicka den till iframen/runtimemiljön och låt sedan runtimemiljön anropa bootstrap med en Bearer-token.

ParameterObligatorisktDetaljer
runtimeBindingIdrekommenderasFöredragen identifierare för aktiva runtimekopplingar.
toolkrävs utan runtimeBindingIddesigner | viewer | configurator | customizer | model-generator
toolIdtool: model-generatorPositivt numeriskt ID för det lokala generatorprojektet, inte dess UUID eller WooCommerce-produktens ID.
originjaOrigin där inbäddningen visas, till exempel https://yourstore.com.
designIden identifierareAlter Product-design-ID. Kombinera inte med orderId.
orderIden identifierareCustomizer-order-ID. Endast giltigt för customizer.
cartKey + cartModenejKundvagnskontext endast för Customizer. cartMode är view eller edit.

Exempel på begäran (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 });

Anmärkningar

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

Exempel på svar

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

Generatorns importendpoints är skrivskyddade anrop mellan servrar. De kräver standardhuvuden för API:t, behörighetsomfånget embed:session:create och en aktiv prenumeration. Importbehörigheten utfärdar ingen redigeringssession och förbrukar inte dess månadskvot. När redigeraren öppnas används samma räknare, monthlyEmbedTokenLimit, som för de andra inbäddade verktygen.

Hitta och importera generatormodeller

Använd /model-generator/models för att lista tillgängliga modeller med generatorer. Beskrivningen generator låser projectId, revision, configurationId, templateRevision, productId och productModel3dId till bestämda värden. Följ dess importPath för att hämta exakt den källrevisionen. Manifest för produktresurser innehåller även generators och varje modells generator-beskrivning. Mallar kan importeras separat per konfiguration och revision.

Katalogfilter

ÄndpunktDetaljer
/model-generator/modelsModellista: name (eller q), categoryId, scope (all, own, global), limit (1–50) och offset.
/model-generator/catalogMallkatalog: generatorType, productId, audience, q, templateKey, configurationId, limit och offset.
/model-generator/projectsProjektlista: configurationId, q, scope (all, own, global), limit och offset. Den publika proxyn använder all som standardvärde för scope.
/model-generator/image-libraries/:kind/assetsTextur-/bakgrundsbibliotek: kind är texture eller background; q, category och mapType filtrerar de tillgängliga resurserna.

En projektimport innehåller document, revision, template och ett files-manifest. Varje fil anger en path under /v1/model-generator/; lägg till /public-api framför sökvägen när filen laddas ned från Alter Product. Kopiera nödvändiga filer till din egen lagring och ersätt källreferenser med lokala referenser. Importera mannequiner och texturbibliotek via deras katalogendpoints; public-files är begränsad till tillåtna resurssökvägar, och mallar måste klara åtkomstkontrollerna för respektive konfiguration och revision.

Exempel på begäran (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 });

Redigeringssession och lokal lagring

Skapa redigeringssessionen med tool: model-generator, ett positivt numeriskt toolId som identifierar det lokala generatorprojektet (inte dess UUID eller WooCommerce-produktens ID) och butikens tillåtna origin. Skicka inte designId, orderId, runtimeBindingId eller varukorgsfält för detta verktyg. Generatorprojektets UUID är en separat identifierare. Skicka den returnerade token via iframe-handskakningen; initieringen av körmiljön returnerar generatorkontexten med 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);

Exempel på svar

{
  "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-meddelanden som används av WordPress-bryggan

WordPress-tillägget tillhandahåller lagringsbryggan och kontrollerar administratörs- eller WooCommerce-butiksansvarigbehörigheter. Det validerar iframe-fönstrets origin, källfönstret, nonce, anrops-ID och tillåtna projektsökvägar. Bryggan skickar lokala läsningar och skrivningar till /wp-json/alter-wc/v1/model-generator. API-autentiseringsuppgifterna stannar på servern. En egen integration måste implementera motsvarande autentiserad lagringshantering; generatorns publika API sparar inte projekt hos Alter Product.

TypBeskrivning
ALTER_CHILD_HELLO / ALTER_PARENT_ACKBarnfönstret inleder handskakningen med en nonce; föräldrafönstret bekräftar samma nonce.
ALTER_CUSTOMIZER_INIT_SESSION / ALTER_CUSTOMIZER_SESSION_READYBarnfönstret begär en redigeringssession för model-generator; föräldrafönstret returnerar en auktoriserad token.
ALTER_MODEL_GENERATOR_REQUESTBarnfönstret skickar requestId, nonce och request med method, path, data och responseType.
ALTER_MODEL_GENERATOR_RESPONSEFöräldrafönstret svarar med samma requestId och nonce samt status, data, headers och eventuella 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.

Vid sparande skickas expectedRevision, templateRevision, document och referenser till resultatfiler. En oföränderlig revision skapas; ett inaktuellt expectedRevision ger HTTP 409. WordPress lagrar metadata i databasen och filer i katalogen uploads. JSON kompakteras och komprimeras med gzip när komprimeringen minskar storleken.

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

Använd sparad modell i design publicerar en fullständig sparad revision i en länkad design. Kunderna ser den sedan genom befintliga Customizer, Configurator eller Viewer med de vanliga produktkopplingarna och prenumerationskontrollerna. Generatorns redigerare förblir ett verktyg för handlaren. Orderkopplingar behåller det sparade projektet och dess revision, så att senare redigeringar inte ändrar tidigare beställningar utan att det märks.

Resurskatalog

Resurskatalogen innehåller produktkällresurser, bakgrunder, miljöer, grafikbiblioteksobjekt, designmallar och mockupresurser. Liständpunkter returnerar lätta beskrivningsobjekt; detaljändpunkter innehåller filmanifest.

TypBeskrivning
productsBasproduktresurser, förhandsvisningar, 3D-modeller samt material- och texturbeskrivningar.
backgroundsStatiska Viewer-bakgrunder.
environmentsMiljökartor och förhandsvisningsbilder.
image_libraryGrafikbiblioteksresurser, inklusive butiksspecifik grafik.
design_templatesFörhandsvisningar av designmallar och referenser till lagerfiler. Stöder filtret product_id.
mockupsMockupgeneratorns resurser, bakgrunder och överläggskartor. Stöder filtret product_id.

Exempel på begäran (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();

Exempel på svar

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

Designimport

Designimport ger åtkomst till designer och deras filer som lagras hos Alter för extern produktion eller migrering. API:et kontrollerar behörighet till Business-planen.

ParameterObligatorisktDetaljer
searchnejSöker efter designtitel eller ID.
offsetnejStandard 0.
limitnejStandard 20, högst 100.

Exempel på begäran (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();

Exempel på svar

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

Filer, typsnitt och valutor

Offentliga förhandsvisningsfiler kan användas i webbläsaren. Skyddade filer kräver en signerad URL eller API-uppgifter med files:read. Typsnitt och valutor har offentliga läsändpunkter.

ÄndpunktÅtkomstDetaljer
/file/public/products/:productId/small.pngoffentligLiten produktförhandsvisning.
/file/public/products/:productId/medium.pngoffentligMedelstor produktförhandsvisning.
/file/public/products/:productId/big.pngoffentligStor produktförhandsvisning.
/file/protected/:keysignerad URL eller files:readSkyddad fil i objektlagring.
/fontsoffentligArray med typsnittsposter.
/currenciesoffentligArray med valutaposter.

Exempel på begäran (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());

Exempel på svar

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

Runtimekopplingar

Runtimekopplingar kopplar externa e-handelsprodukter till Alter Product-designer och runtimetyper. De används främst av WordPress/WooCommerce-integrationer och avancerade butiksbackender.

ParameterObligatorisktDetaljer
designIdnejAlter Product-design-ID som ägs av butiken.
externalProductIdja för synkroniseringExternt produkt-ID, till exempel ett WooCommerce-produkt-ID.
runtimeTypeja för synkroniseringviewer, configurator eller customizer.
statusnejdraft, active, inactive, archived eller legacy_active.
legacyStorefrontProductIdnejValfritt äldre kopplings-ID.
legacyBindingMetanejValfria JSON-metadata, till exempel manifestHash.

Exempel på begäran (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'
          }
        }
      }
    ]
  })
});

Exempel på svar

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

WordPress-anslutningsutbyte

Ändpunkten för WordPress-anslutningsutbyte förbrukar en engångskod och returnerar API-uppgifter till tillägget. Det är inte en allmän ändpunkt för att skapa uppgifter.

Exempel på begäran (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();

Exempel på svar

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

Fel och anropsgränser

De flesta controllerfel normaliseras till ett svar med code. Autentiseringsmiddleware och anropsbegränsare kan i stället returnera ett svar med error.

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

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

{
  "error": "Too Many Requests"
}
TypGränsTidsfönster
Globalt600 anrop60 sekunder
GET /auth/check60 anrop60 sekunder
Läsning av beställningar/produkter300 anrop60 sekunder
Skrivning av beställningar/inbäddningssessioner/runtimekopplingar120 anrop60 sekunder
Läsning av resurser/designimport180 anrop60 sekunder
Typsnitt300 anrop60 sekunder
WP-anslutningsutbyte30 anrop60 sekunder
GET /model-generator/*600 anrop60 sekunder