How to Use Magento 2 API: Complete E-commerce Integration Guide (2026)

Master Magento 2 API integration with this complete guide. Learn authentication, products, orders, customers, inventory MSI, and production e-commerce strategies.

@apidog

@apidog

25 March 2026

How to Use Magento 2 API: Complete E-commerce Integration Guide (2026)

TL;DR

The Magento 2 (Adobe Commerce) API enables developers to integrate with e-commerce stores programmatically. It uses REST, SOAP, and GraphQL endpoints with OAuth 1.0a and token-based authentication, providing access to products, orders, customers, inventory, and more, with configurable rate limits. This guide covers authentication setup, CRUD operations, webhooks, custom endpoints, and production integration strategies.

Introduction

Adobe Commerce (Magento) powers over 250,000 e-commerce stores with $155+ billion in annual gross merchandise value. For developers building e-commerce integrations, ERP connectors, or mobile apps, Magento API integration isn’t optional—it’s essential for reaching this massive merchant base.

Here’s the reality: merchants managing multiple sales channels lose 20-30 hours weekly on manual data entry between Magento and other systems. A solid Magento API integration automates product synchronization, order processing, inventory updates, and customer data management.

This guide walks through the complete Magento 2 API integration process. You’ll learn OAuth 1.0a and token authentication, REST/SOAP/GraphQL endpoints, product and order management, webhooks, custom API development, and production deployment strategies. By the end, you’ll have a production-ready Magento integration.

💡
Apidog simplifies API integration testing. Test your Magento endpoints, validate authentication flows, inspect API responses, and debug integration issues in one workspace. Import API specifications, mock responses, and share test scenarios with your team.
button

What Is the Magento 2 API?

Magento 2 provides three API types for accessing e-commerce data:

The API handles:

Key Features

Feature Description
Multiple Protocols REST, SOAP, GraphQL
OAuth 1.0a Secure third-party access
Token Auth Admin and integration tokens
Webhooks Async operations via queues
Rate Limiting Configurable per installation
Custom Endpoints Extend with custom APIs
Multi-Store Single API, multiple storeviews

API Comparison

API Type Protocol Use Case
REST JSON Mobile apps, integrations
SOAP XML Enterprise systems (SAP, Oracle)
GraphQL GraphQL Storefront, PWA

Magento Versions

Version Status End of Support
Magento 2.4.x Current Active
Adobe Commerce 2.4.x Current Active
Magento 1.x EOL June 2020 (Do not use)

Getting Started: Authentication Setup

Step 1: Create Admin Account or Integration

Before accessing the API:

  1. Log in to Magento Admin Panel
  2. Navigate to System > Permissions > All Users
  3. Create admin user (for admin token) OR
  4. Navigate to System > Extensions > Integrations
  5. Create new integration (for OAuth)

Step 2: Choose Authentication Method

Method Best For Token Lifetime
Admin Token Internal integrations Configurable (default: 4 hours)
Integration Token Third-party apps Until revoked
OAuth 1.0a Public marketplace apps Until revoked
Customer Token Customer-facing apps Configurable

Step 3: Get Admin Token (Simplest Method)

Generate admin token for internal integrations:

const MAGENTO_BASE_URL = process.env.MAGENTO_BASE_URL;
const MAGENTO_ADMIN_USERNAME = process.env.MAGENTO_ADMIN_USERNAME;
const MAGENTO_ADMIN_PASSWORD = process.env.MAGENTO_ADMIN_PASSWORD;

const getAdminToken = async () => {
  const response = await fetch(`${MAGENTO_BASE_URL}/rest/V1/integration/admin/token`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      username: MAGENTO_ADMIN_USERNAME,
      password: MAGENTO_ADMIN_PASSWORD
    })
  });

  if (!response.ok) {
    throw new Error('Invalid admin credentials');
  }

  // Response is a plain string (the token), not JSON
  const token = await response.text();
  return token;
};

// Usage
const token = await getAdminToken();
console.log(`Admin token: ${token}`);
// Store securely - use for subsequent API calls

Security note: Store tokens securely:

# .env file
MAGENTO_BASE_URL="https://store.example.com"
MAGENTO_ADMIN_USERNAME="api_user"
MAGENTO_ADMIN_PASSWORD="secure_password_here"
MAGENTO_ACCESS_TOKEN="obtained_via_auth"

Create integration via Admin Panel:

Go to System > Extensions > Integrations

Click Add New Integration

Fill in details:

Set API Permissions:

Click Save

Click Activate on the new integration

Copy the Access Token and Token Secret

Step 5: Get Customer Token

For customer-facing applications:

const getCustomerToken = async (email, password) => {
  const response = await fetch(`${MAGENTO_BASE_URL}/rest/V1/integration/customer/token`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      username: email,
      password: password
    })
  });

  if (!response.ok) {
    throw new Error('Invalid customer credentials');
  }

  const token = await response.text();
  return token;
};

// Usage
const customerToken = await getCustomerToken('customer@example.com', 'password123');

Step 6: Make Authenticated API Calls

Create reusable API client:

const magentoRequest = async (endpoint, options = {}) => {
  const token = await getAdminToken(); // Or retrieve stored token

  const response = await fetch(`${MAGENTO_BASE_URL}/rest${endpoint}`, {
    ...options,
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Magento API Error: ${error.message}`);
  }

  return response.json();
};

// Usage
const products = await magentoRequest('/V1/products');
console.log(`Found ${products.items.length} products`);

Product Management

Getting Products

Fetch products with filtering:

const getProducts = async (filters = {}) => {
  const params = new URLSearchParams();

  // Build search criteria
  if (filters.search) {
    params.append('searchCriteria[filterGroups][0][filters][0][field]', 'sku');
    params.append('searchCriteria[filterGroups][0][filters][0][value]', `%${filters.search}%`);
    params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'like');
  }

  if (filters.priceFrom) {
    params.append('searchCriteria[filterGroups][1][filters][0][field]', 'price');
    params.append('searchCriteria[filterGroups][1][filters][0][value]', filters.priceFrom);
    params.append('searchCriteria[filterGroups][1][filters][0][conditionType]', 'gteq');
  }

  params.append('searchCriteria[pageSize]', filters.limit || 20);
  params.append('searchCriteria[currentPage]', filters.page || 1);

  const response = await magentoRequest(`/V1/products?${params.toString()}`);
  return response;
};

// Usage
const products = await getProducts({ search: 'shirt', priceFrom: 20, limit: 50 });

products.items.forEach(product => {
  console.log(`${product.sku}: ${product.name} - $${product.price}`);
});

Getting Single Product

Fetch product by SKU:

const getProduct = async (sku) => {
  const response = await magentoRequest(`/V1/products/${sku}`);
  return response;
};

// Usage
const product = await getProduct('TSHIRT-001');
console.log(`Name: ${product.name}`);
console.log(`Price: $${product.price}`);
console.log(`Stock: ${product.extension_attributes?.stock_item?.qty}`);

Creating a Product

Create simple product:

const createProduct = async (productData) => {
  const product = {
    product: {
      sku: productData.sku,
      name: productData.name,
      attribute_set_id: productData.attributeSetId || 4, // Default set
      type_id: 'simple',
      price: productData.price,
      status: productData.status || 1, // 1=enabled, 2=disabled
      visibility: productData.visibility || 4, // 4=Catalog & Search
      weight: productData.weight || 1,
      extension_attributes: {
        stock_item: {
          qty: productData.qty || 0,
          is_in_stock: productData.qty > 0 ? true : false
        }
      },
      custom_attributes: [
        {
          attribute_code: 'description',
          value: productData.description
        },
        {
          attribute_code: 'short_description',
          value: productData.shortDescription
        },
        {
          attribute_code: 'color',
          value: productData.color
        },
        {
          attribute_code: 'size',
          value: productData.size
        }
      ]
    }
  };

  const response = await magentoRequest('/V1/products', {
    method: 'POST',
    body: JSON.stringify(product)
  });

  return response;
};

// Usage
const newProduct = await createProduct({
  sku: 'TSHIRT-NEW-001',
  name: 'Premium Cotton T-Shirt',
  price: 29.99,
  qty: 100,
  description: 'High-quality cotton t-shirt',
  shortDescription: 'Premium cotton tee',
  color: 'Blue',
  size: 'M'
});

console.log(`Product created: ${newProduct.id}`);

Updating a Product

Update product information:

const updateProduct = async (sku, updates) => {
  const product = {
    product: {
      sku: sku,
      ...updates
    }
  };

  const response = await magentoRequest(`/V1/products/${sku}`, {
    method: 'PUT',
    body: JSON.stringify(product)
  });

  return response;
};

// Usage - Update price and stock
await updateProduct('TSHIRT-001', {
  price: 24.99,
  extension_attributes: {
    stock_item: {
      qty: 150,
      is_in_stock: true
    }
  }
});

Deleting a Product

Remove product:

const deleteProduct = async (sku) => {
  await magentoRequest(`/V1/products/${sku}`, {
    method: 'DELETE'
  });

  console.log(`Product ${sku} deleted`);
};

Product Types

Type Description Use Case
Simple Single SKU, no variations Standard products
Configurable Parent with child variations Size/color options
Grouped Collection of simple products Product bundles
Virtual Non-physical products Services, downloads
Bundle Customizable product bundles Build-your-own kits
Downloadable Digital products E-books, software

Order Management

Getting Orders

Fetch orders with filtering:

const getOrders = async (filters = {}) => {
  const params = new URLSearchParams();

  if (filters.status) {
    params.append('searchCriteria[filterGroups][0][filters][0][field]', 'status');
    params.append('searchCriteria[filterGroups][0][filters][0][value]', filters.status);
    params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'eq');
  }

  if (filters.dateFrom) {
    params.append('searchCriteria[filterGroups][1][filters][0][field]', 'created_at');
    params.append('searchCriteria[filterGroups][1][filters][0][value]', filters.dateFrom);
    params.append('searchCriteria[filterGroups][1][filters][0][conditionType]', 'gteq');
  }

  params.append('searchCriteria[pageSize]', filters.limit || 20);
  params.append('searchCriteria[currentPage]', filters.page || 1);

  const response = await magentoRequest(`/V1/orders?${params.toString()}`);
  return response;
};

// Usage - Get pending orders from last 7 days
const orders = await getOrders({
  status: 'pending',
  dateFrom: '2026-03-18 00:00:00',
  limit: 50
});

orders.items.forEach(order => {
  console.log(`Order #${order.increment_id}: ${order.customer_email} - $${order.grand_total}`);
});

Getting Single Order

Fetch order by ID:

const getOrder = async (orderId) => {
  const response = await magentoRequest(`/V1/orders/${orderId}`);
  return response;
};

// Usage
const order = await getOrder(12345);
console.log(`Order #${order.increment_id}`);
console.log(`Status: ${order.status}`);
console.log(`Total: $${order.grand_total}`);
console.log(`Items:`);
order.items.forEach(item => {
  console.log(`  - ${item.name} x ${item.qty_ordered}`);
});

Order Status Flow

pending → processing → complete
        → canceled
        → on_hold
        → payment_review

Updating Order Status

Change order status:

const updateOrderStatus = async (orderId, newStatus) => {
  // Note: Direct status update requires custom endpoint
  // Use order management workflow instead:

  // For cancel:
  await magentoRequest(`/V1/orders/${orderId}/cancel`, {
    method: 'POST'
  });

  // For hold:
  await magentoRequest(`/V1/orders/${orderId}/hold`, {
    method: 'POST'
  });

  // For unhold:
  await magentoRequest(`/V1/orders/${orderId}/unhold`, {
    method: 'POST'
  });
};

Creating Invoice

Generate invoice for order:

const createInvoice = async (orderId, items = [], notify = true, appendComment = false, comment = null) => {
  const invoice = {
    capture: true, // true = capture payment
    last: true,
    items: items // Array of {order_item_id, qty}
  };

  if (comment) {
    invoice.comment = comment;
    invoice.notify_customer = notify ? 1 : 0;
    invoice.append_comment = appendComment ? 1 : 0;
  }

  const response = await magentoRequest(`/V1/order/${orderId}/invoice`, {
    method: 'POST',
    body: JSON.stringify(invoice)
  });

  return response;
};

// Usage - Invoice and capture full order
const invoiceId = await createInvoice(12345, [], true, false, 'Thank you for your order!');
console.log(`Invoice created: ${invoiceId}`);

Creating Shipment

Ship order:

const createShipment = async (orderId, items = [], notify = true, appendComment = false, comment = null, tracks = []) => {
  const shipment = {
    items: items, // Array of {order_item_id, qty}
    notify: notify ? 1 : 0,
    append_comment: appendComment ? 1 : 0,
    comment: comment,
    tracks: tracks // Array of {track_number, title, carrier_code}
  };

  const response = await magentoRequest(`/V1/order/${orderId}/ship`, {
    method: 'POST',
    body: JSON.stringify(shipment)
  });

  return response;
};

// Usage - Ship with tracking
const shipmentId = await createShipment(12345, [], true, false, 'Your order has shipped!', [
  {
    track_number: '1Z999AA10123456784',
    title: 'Tracking Number',
    carrier_code: 'ups'
  }
]);
console.log(`Shipment created: ${shipmentId}`);

Customer Management

Getting Customers

Fetch customers:

const getCustomers = async (filters = {}) => {
  const params = new URLSearchParams();

  if (filters.email) {
    params.append('searchCriteria[filterGroups][0][filters][0][field]', 'email');
    params.append('searchCriteria[filterGroups][0][filters][0][value]', filters.email);
    params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'eq');
  }

  params.append('searchCriteria[pageSize]', filters.limit || 20);

  const response = await magentoRequest(`/V1/customers/search?${params.toString()}`);
  return response;
};

// Usage
const customers = await getCustomers({ email: 'customer@example.com' });
customers.items.forEach(customer => {
  console.log(`${customer.firstname} ${customer.lastname} - ${customer.email}`);
});

Creating a Customer

Register new customer:

const createCustomer = async (customerData) => {
  const customer = {
    customer: {
      websiteId: customerData.websiteId || 1,
      email: customerData.email,
      firstname: customerData.firstname,
      lastname: customerData.lastname,
      middlename: customerData.middlename || '',
      gender: customerData.gender || 0,
      store_id: customerData.storeId || 0,
      extension_attributes: {
        is_subscribed: customerData.subscribed || false
      }
    },
    password: customerData.password
  };

  const response = await magentoRequest('/V1/customers', {
    method: 'POST',
    body: JSON.stringify(customer)
  });

  return response;
};

// Usage
const newCustomer = await createCustomer({
  email: 'newcustomer@example.com',
  firstname: 'John',
  lastname: 'Doe',
  password: 'SecurePass123!',
  subscribed: true
});

console.log(`Customer created: ID ${newCustomer.id}`);

Inventory Management (MSI)

Getting Stock Status

Check product stock:

const getStockStatus = async (sku) => {
  const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`);
  return response;
};

// Usage
const stock = await getStockStatus('TSHIRT-001');
console.log(`Qty: ${stock.qty}`);
console.log(`In Stock: ${stock.is_in_stock}`);
console.log(`Min Qty: ${stock.min_qty}`);

Updating Stock

Update product quantity:

const updateStock = async (sku, qty, isInStock = null) => {
  const stockItem = {
    stockItem: {
      qty: qty,
      is_in_stock: isInStock !== null ? isInStock : qty > 0
    }
  };

  const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`, {
    method: 'PUT',
    body: JSON.stringify(stockItem)
  });

  return response;
};

// Usage
await updateStock('TSHIRT-001', 100, true);

Webhooks and Async Operations

Setting Up Webhooks

Magento uses message queues for async notifications:

// Magento doesn't have native webhooks
// Use these approaches instead:

// 1. Poll orders endpoint periodically
const pollNewOrders = async (lastOrderId) => {
  const orders = await getOrders({
    dateFrom: new Date().toISOString()
  });

  const newOrders = orders.items.filter(o => o.id > lastOrderId);
  return newOrders;
};

// 2. Use Adobe I/O Events (Adobe Commerce only)
// Configure events in Adobe Developer Console

// 3. Create custom webhook module
// See: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/message-queues/message-queues.html

Rate Limiting

Understanding Rate Limits

Magento rate limits are configurable:

Configure in Admin: Stores > Configuration > Services > Web API > Security

Implementing Rate Limit Handling

const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await magentoRequest(endpoint, options);
      return response;
    } catch (error) {
      if (error.message.includes('429') && attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
};

Production Deployment Checklist

Before going live:

Real-World Use Cases

ERP Integration

A manufacturer syncs inventory:

Mobile App

A retailer builds shopping app:

Conclusion

The Magento 2 API provides comprehensive e-commerce functionality. Key takeaways:

button

FAQ Section

How do I authenticate with Magento API?

Use admin token for internal integrations or create an Integration in System > Extensions for OAuth. Customer token for customer-facing apps.

What is the difference between REST and GraphQL in Magento?

REST provides full CRUD operations. GraphQL is optimized for frontend queries with efficient data fetching.

How do I create a product via API?

POST to /V1/products with product data including SKU, name, price, and stock_item in extension_attributes.

Can I get webhooks for new orders?

Magento doesn’t have native webhooks. Use polling, Adobe I/O Events (Adobe Commerce), or create custom module.

How do I update stock quantities?

PUT to /V1/products/{sku}/stockItems/1 with qty and is_in_stock values.

Explore more

How to Use Make (Integromat) API ?

How to Use Make (Integromat) API ?

Master Make (Integromat) API integration with this complete guide. Learn scenario management, webhooks, execution monitoring, and production automation strategies.

25 March 2026

How Do You Build a HIPAA-Compliant API in 2026 for Secure Healthcare Applications?

How Do You Build a HIPAA-Compliant API in 2026 for Secure Healthcare Applications?

Complete guide to HIPAA-compliant API development. Learn PHI handling, encryption, access controls, audit logging, and compliance verification for healthcare applications.

25 March 2026

How to Use AWS Lambda API for Serverless in 2026

How to Use AWS Lambda API for Serverless in 2026

Master AWS Lambda API integration with this complete guide. Learn IAM authentication, function deployment, invocation patterns, event sources, and serverless architecture.

25 March 2026

Practice API Design-first in Apidog

Discover an easier way to build and use APIs