Alter Product Public API — integracja Public API służy do integracji server-to-server ze storefrontami, backendami sklepów, pluginami WordPress/WooCommerce i zewnętrznymi procesami produkcyjnymi.
Spis treści https://alterproduct.com/public-api/v1
Dane dostępowe API wygenerujesz w ustawieniach e-commerce. Access Token jest pokazywany tylko raz, więc od razu zapisz go w backendowym storage sekretów.
Access Key i Access Token trzymaj wyłącznie po stronie serwera. Uwierzytelnione endpointy odrzucają wywołania przeglądarkowe z nagłówkami Origin lub Referer.
Dane dostępowe mogą mieć scope’y. Użyj GET /auth/check, żeby sprawdzić aktywny storefront, możliwości planu i scope’y przypisane do credentiala.
x-alter-access-key: YOUR_API_KEY
x-alter-access-token: YOUR_API_TOKENParametr Wymagany Szczegóły x-alter-access-keytak Publiczny identyfikator credentiala. x-alter-access-tokentak Sekretny token sparowany z access key. x-alter-client-fingerprintnie Opcjonalny stabilny fingerprint używany przy limitach sesji embed. Authorizationtylko runtime Token Bearer zwrócony przez POST /embed/session, używany przez /runtime/bootstrap.
Użyj endpointu auth check przed włączeniem synchronizacji lub funkcji embed w produkcyjnej integracji.
GET https://alterproduct.com/public-api/v1/auth/check Przykładowe zapytanie (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 ) ; Przykładowa odpowiedź
{
"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
}
}
} Poniższy helper jest używany w pozostałych przykładach. To zwykły fetch i działa w Node.js 18+ lub dowolnym runtime serwerowym z 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 ;
} Tabela odzwierciedla publiczne routy montowane w backend-public-api/app.js. Ścieżki pokazują publiczny prefiks reverse proxy używany przez integracje zewnętrzne.
Metoda Endpoint Opis Dostęp GET/public-api/healthzHealth check serwisu. publicznyGET/public-api/v1/auth/checkWaliduje credentiale i zwraca storefront, scope’y oraz możliwości planu. dowolny uwierzytelniony credentialGET/public-api/v1/customer-ordersZwraca paginowaną i filtrowalną listę zamówień klientów. orders:readGET/public-api/v1/customer-orders/:idZwraca pojedyncze zamówienie klienta ze skonfigurowanymi pozycjami. orders:readPOST/public-api/v1/customer-orders/batchZwraca maksymalnie 100 zamówień na podstawie ID. orders:readPATCH/public-api/v1/customer-orders/:id/statusAktualizuje status zamówienia. orders:writePATCH/public-api/v1/customer-orders/:orderId/quantityAktualizuje ilości wybranych pozycji zamówienia. orders:writePATCH/public-api/v1/customer-orders/:orderId/quantity/allUstawia jedną ilość dla wszystkich pozycji zamówienia. orders:writeDELETE/public-api/v1/customer-orders/:idUsuwa zamówienie klienta należące do właściciela storefrontu. orders:writeGET/public-api/v1/productsZwraca produkty/designy storefrontu z dostępnością embed i URL-ami mediów. products:readGET/public-api/v1/products/:idZwraca pojedynczy produkt/design storefrontu. products:readPOST/public-api/v1/embed/sessionWystawia krótko żyjący JWT dla runtime designer/viewer/configurator/customizer. embed:session:createGET/public-api/v1/runtime/bootstrapRozwiązuje kontekst runtime z tokenu embed JWT. token embed BearerGET/public-api/v1/assetsListuje assety katalogu dla wskazanego typu. dowolny uwierzytelniony credentialGET/public-api/v1/assets/:type/:assetIdZwraca manifest assetu z rolami plików do pobrania. dowolny uwierzytelniony credentialGET/public-api/v1/assets/:type/:assetId/files/:rolePobiera plik assetu po roli. dowolny uwierzytelniony credentialGET/public-api/v1/design-importsListuje designy dostępne do importu. uwierzytelniony credential, wymagany plan BusinessGET/public-api/v1/design-imports/:idZwraca payload importu designu i deskryptory plików. uwierzytelniony credential, wymagany plan BusinessGET/public-api/v1/design-imports/:id/files/:fileIdPobiera plik z deskryptora importu designu. uwierzytelniony credential, wymagany plan BusinessGET/public-api/v1/file/public/products/:productId/:sizeZwraca publiczny podgląd produktu. Size musi mieć wartość small.png, medium.png albo big.png. publicznyGET/public-api/v1/file/protected/:keyZwraca chroniony plik po storage key. podpisany URL albo files:readGET/public-api/v1/fontsZwraca wszystkie dostępne fonty. publicznyGET/public-api/v1/currenciesZwraca wszystkie waluty. publicznyPOST/public-api/v1/runtime-bindings/sync-from-wordpressTworzy lub aktualizuje runtime bindings z mapowań produktów WordPress. dowolny uwierzytelniony credentialPATCH/public-api/v1/runtime-bindings/:idAktualizuje runtime binding. dowolny uwierzytelniony credentialPOST/public-api/v1/runtime-bindings/:id/activateAktywuje runtime binding. dowolny uwierzytelniony credentialPOST/public-api/v1/runtime-bindings/:id/deactivateDezaktywuje runtime binding. dowolny uwierzytelniony credentialPOST/public-api/v1/wp-connect/exchangeWymienia kod handoff WordPress auto-connect na credentiale API. jednorazowy kod handoff
Endpointy zamówień pozwalają zewnętrznemu sklepowi odczytać skonfigurowane pozycje, zmienić ilości, przesuwać zamówienie między statusami realizacji i usuwać porzucone zamówienia.
Parametr Wymagany Szczegóły namenieSzuka po nazwie designu oraz numerycznym ID zamówienia. category_idnieFiltruje po ID kategorii produktu. order_statusnieJedna z dozwolonych wartości statusu. offsetnieDomyślnie 0. Musi być >= 0. limitnieDomyślnie 9 dla tego kontrolera, maksymalnie 50. order_bynieid, created_at albo design_name. directionnieASC albo DESC.
Przykładowe zapytanie (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 ]
} )
} ) ; Dozwolone wartości
Status Opis shopping_cartFlow koszyka; klient nadal może edytować konfigurację. editableZamówienie pozostaje edytowalne przez klienta. paidZamówienie jest opłacone i gotowe do realizacji. processingZamówienie jest w realizacji. completedZamówienie zostało zrealizowane. cancelledZamówienie zostało anulowane.
Przykładowe zapytanie (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'
} ) ; Przykładowa odpowiedź
{
"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" }
}
} Endpointy produktów zwracają designy storefrontu, które można osadzać jako viewer, configurator albo customizer.
Parametr Wymagany Szczegóły namenieSzuka po nazwie produktu/designu. customizernietrue albo false. offsetnieDomyślnie 0. Musi być >= 0. limitnieDomyślnie 9, maksymalnie 50. order_bynieid, name albo created_at. directionnieASC albo DESC.
Przykładowe zapytanie (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' ) ; Przykładowa odpowiedź
{
"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
}
} Utwórz krótko żyjący token embed po stronie serwera, przekaż go do iframe/runtime, a następnie runtime pobiera kontekst przez bootstrap z tokenem Bearer.
Parametr Wymagany Szczegóły runtimeBindingIdzalecanyPreferowany identyfikator aktywnego runtime bindingu. toolwymagany bez runtimeBindingIddesigner, viewer, configurator albo customizer. origintakOrigin, na którym renderowany jest embed, np. https://yourstore.com. designIdjeden identyfikatorID designu Alter Product. Nie łącz z orderId. orderIdjeden identyfikatorID zamówienia customizera. Działa tylko dla customizera. cartKey + cartModenieKontekst koszyka tylko dla customizera. cartMode to view albo edit.
Przykładowe zapytanie (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 } ) ; Uwagi
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
} )
} ) ; Przykładowa odpowiedź
{
"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
} Katalog assetów udostępnia produkty bazowe, tła, środowiska, bibliotekę grafik, szablony designów i assety mockupów. Lista zwraca lekkie deskryptory, a szczegóły zawierają manifest plików.
Typ Opis productsAssety produktów bazowych, podglądy, modele 3D oraz deskryptory materiałów i tekstur. backgroundsStatyczne tła viewera. environmentsMapy środowisk i obrazy podglądu. image_libraryAssety biblioteki grafik, także grafiki scoped do storefrontu. design_templatesPodglądy szablonów designów i referencje plików warstw. Obsługuje filtr product_id. mockupsAssety generatora mockupów, tła i mapy overlay. Obsługuje filtr product_id.
Przykładowe zapytanie (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 ( ) ; Przykładowa odpowiedź
{
"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
} Importy designów udostępniają designy hostowane w Alter Product oraz ich pliki dla zewnętrznej produkcji lub migracji. API sprawdza dostępność funkcji w planie Business.
Parametr Wymagany Szczegóły searchnieSzuka po tytule designu lub ID. offsetnieDomyślnie 0. limitnieDomyślnie 20, maksymalnie 100.
Przykładowe zapytanie (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 ( ) ; Przykładowa odpowiedź
{
"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
} Publiczne pliki podglądu są przyjazne dla przeglądarki. Chronione pliki wymagają podpisanego URL-a albo credentiala API ze scope files:read. Fonty i waluty są publicznymi endpointami read.
Endpoint Dostęp Szczegóły /file/public/products/:productId/small.pngpublicznyMały podgląd produktu. /file/public/products/:productId/medium.pngpublicznyŚredni podgląd produktu. /file/public/products/:productId/big.pngpublicznyDuży podgląd produktu. /file/protected/:keypodpisany URL albo files:readChroniony plik ze storage. /fontspublicznyTablica rekordów fontów. /currenciespublicznyTablica rekordów walut.
Przykładowe zapytanie (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 ( ) ) ; Przykładowa odpowiedź
[
{
"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
}
] Runtime bindings łączą zewnętrzne produkty commerce z designami Alter Product i typami runtime. Używają ich głównie integracje WordPress/WooCommerce oraz zaawansowane backendy storefrontu.
Parametr Wymagany Szczegóły designIdnieID designu Alter Product należącego do storefrontu. externalProductIdtak dla syncZewnętrzne ID produktu, np. ID produktu WooCommerce. runtimeTypetak dla syncviewer, configurator albo customizer. statusniedraft, active, inactive, archived albo legacy_active. legacyStorefrontProductIdnieOpcjonalne ID legacy mappingu. legacyBindingMetanieOpcjonalne metadane JSON, np. manifestHash.
Przykładowe zapytanie (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'
}
}
}
]
} )
} ) ; Przykładowa odpowiedź
{
"message" : "runtimeBinding.syncCompleted" ,
"runtimeBindings" : [
{
"id" : 42 ,
"designId" : 381 ,
"externalProductId" : "wc_123" ,
"runtimeType" : "customizer" ,
"status" : "active"
}
]
} Endpoint WordPress connect exchange zużywa jednorazowy kod handoff i zwraca credentiale API do pluginu. To nie jest ogólny endpoint do tworzenia credentiali.
Przykładowe zapytanie (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 ( ) ; Przykładowa odpowiedź
{
"message" : "wpConnect.exchange.ok" ,
"accessKey" : "generated-access-key" ,
"accessToken" : "generated-access-token" ,
"storefrontId" : 12
} Większość błędów kontrolerów jest normalizowana do odpowiedzi z code. Middleware uwierzytelniania i limitery mogą zwrócić odpowiedź z error.
// Controller error
{
"code" : "assetCatalog.invalidType"
}
// Auth middleware or rate limit
{
"error" : "Unauthorized"
}
{
"error" : "Too Many Requests"
} Typ Limit Okno Globalnie600 zapytań 60 sekund GET /auth/check60 zapytań 60 sekund Orders read/products read300 zapytań 60 sekund Orders write/embed sessions/runtime bindings120 zapytań 60 sekund Assets/design imports read180 zapytań 60 sekund Fonts300 zapytań 60 sekund WP connect exchange30 zapytań 60 sekund