Inicio rápido
Tu primera llamada, solo lectura
Crea un token, identifica tu tienda y consulta sus productos desde un servidor.
La API usa producción, aunque los pagos estén en sandbox. Los IDs y las respuestas de esta guía son ficticios; reemplázalos por los de tu tienda.
Crea un token de solo lectura
En API e integraciones, elige la tienda, el acceso solo lectura y un vencimiento. El secreto se muestra una sola vez; guárdalo en una variable de entorno del servidor llamada
MOKU_PAT.No pegues el token en estas páginas, URLs, repositorios ni JavaScript del navegador. Incluso un token de lectura permite ver datos personales de pedidos: protege su almacenamiento y sus logs.
Permisos, vencimiento y revocaciónRequisitos de los ejemplos
Los ejemplos cURL usan una terminal de servidor. Los ejemplos PHP son programas para PHP CLI y requieren la extensión cURL; no son un plugin ni código para pegar directamente en WordPress. Ambos leen
MOKU_PATdesde el entorno y muestran la respuesta sin incluir el token.Obtén el ID de tu tienda
Envía el token como
Authorization: Bearer. En v1, un PAT válido autoriza una sola tienda: guardadata[0].idy úsalo comovendor_iden las siguientes rutas.Tienda vinculada al PAT
Solicitud · ejemplo ilustrativo
cURL
: "${MOKU_PAT:?}" && curl --silent --show-error --fail-with-body \ 'https://moku.cl/api/v1/vendors' \ --header "Authorization: Bearer ${MOKU_PAT}" \ --header 'Accept: application/json'PHP
Ejemplo para PHP CLI con la extensión cURL. No es un plugin de WordPress ni debe ejecutarse en el navegador.
<?php $token = getenv('MOKU_PAT'); if ($token === false || $token === '') { throw new RuntimeException('MOKU_PAT'); } $url = 'https://moku.cl/api/v1/vendors'; $curl = curl_init($url); if ($curl === false) { throw new RuntimeException('curl_init'); } curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => [ 'Accept: application/json', 'Authorization: Bearer ' . $token, ], ]); $response = curl_exec($curl); if ($response === false) { $message = curl_error($curl); curl_close($curl); throw new RuntimeException($message); } $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); $result = json_decode($response, false, 512, JSON_THROW_ON_ERROR); $failed = $status < 200 || $status >= 300; if ($failed) { fwrite(STDERR, "HTTP {$status}\n"); } fwrite( $failed ? STDERR : STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR) . PHP_EOL ); exit($failed ? 1 : 0);Respuesta 200
application/json{ "data": [ { "id": "vendor_demo_ceramica", "name": "Cerámica de ejemplo", "slug": "ceramica-de-ejemplo" } ] }¿La respuesta es 401?
Un token ausente, vencido, revocado o que ya no corresponde al dueño de la tienda falla con
UNAUTHENTICATED, no con una lista vacía. Revisa la credencial; no registres su valor.Token ausente o no válido
Solicitud · ejemplo ilustrativo
cURL
curl --silent --show-error --fail-with-body \ 'https://moku.cl/api/v1/vendors' \ --header 'Accept: application/json'PHP
Ejemplo para PHP CLI con la extensión cURL. No es un plugin de WordPress ni debe ejecutarse en el navegador.
<?php $url = 'https://moku.cl/api/v1/vendors'; $curl = curl_init($url); if ($curl === false) { throw new RuntimeException('curl_init'); } curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => [ 'Accept: application/json', ], ]); $response = curl_exec($curl); if ($response === false) { $message = curl_error($curl); curl_close($curl); throw new RuntimeException($message); } $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); $result = json_decode($response, false, 512, JSON_THROW_ON_ERROR); $failed = $status < 200 || $status >= 300; if ($failed) { fwrite(STDERR, "HTTP {$status}\n"); } fwrite( $failed ? STDERR : STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR) . PHP_EOL ); exit($failed ? 1 : 0);Respuesta 401
application/problem+json{ "type": "https://developers.moku.cl/reference/errors/#unauthenticated", "title": "Authentication required", "status": 401, "code": "UNAUTHENTICATED", "detail": "Provide a valid Moku personal access token.", "request_id": "req_00000000000000000000000000000002" }Lista tus productos
Reemplaza el ID ficticio de la URL por el recibido en el paso anterior. La respuesta incluye productos en todos sus estados de publicación; una lectura no publica ni modifica nada.
Primera página de productos
Solicitud · ejemplo ilustrativo
cURL
: "${MOKU_PAT:?}" && curl --silent --show-error --fail-with-body \ 'https://moku.cl/api/v1/vendors/vendor_demo_ceramica/products' \ --header "Authorization: Bearer ${MOKU_PAT}" \ --header 'Accept: application/json' \ --get \ --data-urlencode 'limit=1'PHP
Ejemplo para PHP CLI con la extensión cURL. No es un plugin de WordPress ni debe ejecutarse en el navegador.
<?php $token = getenv('MOKU_PAT'); if ($token === false || $token === '') { throw new RuntimeException('MOKU_PAT'); } $url = 'https://moku.cl/api/v1/vendors/vendor_demo_ceramica/products'; $query = [ 'limit' => '1', ]; $url .= '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = curl_init($url); if ($curl === false) { throw new RuntimeException('curl_init'); } curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => [ 'Accept: application/json', 'Authorization: Bearer ' . $token, ], ]); $response = curl_exec($curl); if ($response === false) { $message = curl_error($curl); curl_close($curl); throw new RuntimeException($message); } $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); $result = json_decode($response, false, 512, JSON_THROW_ON_ERROR); $failed = $status < 200 || $status >= 300; if ($failed) { fwrite(STDERR, "HTTP {$status}\n"); } fwrite( $failed ? STDERR : STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR) . PHP_EOL ); exit($failed ? 1 : 0);Respuesta 200
application/json{ "data": [ { "id": "product_demo_tazon", "vendor_id": "vendor_demo_ceramica", "catalog_status": "active", "status": "published", "revision": 3, "kind": "variable", "name": "Tazón de cerámica", "slug": "tazon-de-ceramica", "description": "Tazón de cerámica hecho a mano.", "price": 15000, "original_price": null, "discount": 0, "category": "hogar", "subcategory": "ceramica", "image_urls": [ "https://example.com/tazon-azul.jpg" ], "badge": null, "options": { "Color": [ "Azul" ] }, "default_options": { "Color": "Azul" }, "variations": [ { "id": "variation_demo_azul", "status": "active", "options": { "Color": "Azul" }, "price": 15000, "original_price": null, "sku": "TAZ-AZUL" } ], "features": [ "Hecho a mano" ], "related_product_ids": [], "tags": [ "ceramica" ], "sku": null, "weight_kg": 0.4, "source_region": "metropolitana", "created_at": "2026-08-01T12:00:00.000Z", "updated_at": "2026-08-26T09:00:00.000Z", "published_at": "2026-08-01T12:00:00.000Z", "archived_at": null } ], "page": { "next_cursor": "eyJ2IjoxLCJraW5kIjoicHJvZHVjdCIsInZlbmRvcklkIjoidmVuZG9yX2RlbW9fY2VyYW1pY2EiLCJwcm9kdWN0SWQiOiJwcm9kdWN0X2RlbW9fdGF6b24ifQ.KalmHw2-bJJUEJF6PFqDKKyNmWuniEUIYAG3mWI_TM4" } }Una tienda sin productos también responde 200
Una respuesta con
data: []ypage.next_cursor: nulles válida. Muestra un estado vacío y termina la lectura; no crees productos automáticamente para completar esta guía.Catálogo vacío
Solicitud · ejemplo ilustrativo
cURL
: "${MOKU_PAT:?}" && curl --silent --show-error --fail-with-body \ 'https://moku.cl/api/v1/vendors/vendor_demo_ceramica/products' \ --header "Authorization: Bearer ${MOKU_PAT}" \ --header 'Accept: application/json' \ --get \ --data-urlencode 'limit=1'PHP
Ejemplo para PHP CLI con la extensión cURL. No es un plugin de WordPress ni debe ejecutarse en el navegador.
<?php $token = getenv('MOKU_PAT'); if ($token === false || $token === '') { throw new RuntimeException('MOKU_PAT'); } $url = 'https://moku.cl/api/v1/vendors/vendor_demo_ceramica/products'; $query = [ 'limit' => '1', ]; $url .= '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = curl_init($url); if ($curl === false) { throw new RuntimeException('curl_init'); } curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => [ 'Accept: application/json', 'Authorization: Bearer ' . $token, ], ]); $response = curl_exec($curl); if ($response === false) { $message = curl_error($curl); curl_close($curl); throw new RuntimeException($message); } $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); $result = json_decode($response, false, 512, JSON_THROW_ON_ERROR); $failed = $status < 200 || $status >= 300; if ($failed) { fwrite(STDERR, "HTTP {$status}\n"); } fwrite( $failed ? STDERR : STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR) . PHP_EOL ); exit($failed ? 1 : 0);Respuesta 200
application/json{ "data": [], "page": { "next_cursor": null } }Ver campos y errores de listar productosCómo leer la siguiente página
Si
page.next_cursorno esnull, cópialo sin modificar al parámetropage_afterde la misma colección y con el mismo token. La muestra usa un cursor ficticio: usa siempre el que te devuelva la API.Página siguiente de productos
Solicitud · ejemplo ilustrativo
cURL
: "${MOKU_PAT:?}" && curl --silent --show-error --fail-with-body \ 'https://moku.cl/api/v1/vendors/vendor_demo_ceramica/products' \ --header "Authorization: Bearer ${MOKU_PAT}" \ --header 'Accept: application/json' \ --get \ --data-urlencode 'limit=1' \ --data-urlencode 'page_after=eyJ2IjoxLCJraW5kIjoicHJvZHVjdCIsInZlbmRvcklkIjoidmVuZG9yX2RlbW9fY2VyYW1pY2EiLCJwcm9kdWN0SWQiOiJwcm9kdWN0X2RlbW9fdGF6b24ifQ.KalmHw2-bJJUEJF6PFqDKKyNmWuniEUIYAG3mWI_TM4'PHP
Ejemplo para PHP CLI con la extensión cURL. No es un plugin de WordPress ni debe ejecutarse en el navegador.
<?php $token = getenv('MOKU_PAT'); if ($token === false || $token === '') { throw new RuntimeException('MOKU_PAT'); } $url = 'https://moku.cl/api/v1/vendors/vendor_demo_ceramica/products'; $query = [ 'limit' => '1', 'page_after' => 'eyJ2IjoxLCJraW5kIjoicHJvZHVjdCIsInZlbmRvcklkIjoidmVuZG9yX2RlbW9fY2VyYW1pY2EiLCJwcm9kdWN0SWQiOiJwcm9kdWN0X2RlbW9fdGF6b24ifQ.KalmHw2-bJJUEJF6PFqDKKyNmWuniEUIYAG3mWI_TM4', ]; $url .= '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = curl_init($url); if ($curl === false) { throw new RuntimeException('curl_init'); } curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => [ 'Accept: application/json', 'Authorization: Bearer ' . $token, ], ]); $response = curl_exec($curl); if ($response === false) { $message = curl_error($curl); curl_close($curl); throw new RuntimeException($message); } $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); $result = json_decode($response, false, 512, JSON_THROW_ON_ERROR); $failed = $status < 200 || $status >= 300; if ($failed) { fwrite(STDERR, "HTTP {$status}\n"); } fwrite( $failed ? STDERR : STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR) . PHP_EOL ); exit($failed ? 1 : 0);Respuesta 200
application/json{ "data": [ { "id": "product_demo_vaso", "vendor_id": "vendor_demo_ceramica", "catalog_status": "active", "status": "published", "revision": 1, "kind": "simple", "name": "Vaso de greda", "slug": "vaso-de-greda", "description": "Vaso de greda hecho a mano.", "price": 12000, "original_price": null, "discount": 0, "category": "hogar", "subcategory": "ceramica", "image_urls": [ "https://example.com/vaso-greda.jpg" ], "badge": null, "options": {}, "default_options": null, "variations": [], "features": [ "Hecho a mano" ], "related_product_ids": [], "tags": [ "ceramica" ], "sku": "VAS-GREDA", "weight_kg": 0.3, "source_region": "metropolitana", "created_at": "2026-08-01T12:00:00.000Z", "updated_at": "2026-08-26T09:00:00.000Z", "published_at": "2026-08-01T12:00:00.000Z", "archived_at": null } ], "page": { "next_cursor": null } }Detente cuando el cursor sea
null. Las páginas no son una foto inmutable: el catálogo puede cambiar entre lecturas; conserva los IDs y reconcilia diferencias.
Del producto al stock
Sigue con una comparación de inventario sin escrituras. Después acuerda con el vendedor qué sistema será la fuente de verdad antes de habilitar cualquier cambio.