> ## Documentation Index
> Fetch the complete documentation index at: https://developers.semji.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect Magento to Semji

> Step-by-step guide to connect your Magento 2 store to Semji through the REST Admin API and an Integration access token, so AI agents can read and update CMS pages, blocks, product and category content.

Semji connects to Magento through the **REST Admin API**, authenticating every
request with an **Integration access token** sent as a Bearer credential. Once
connected, Semji's AI agents can work on the four kinds of content a Magento
store carries: **CMS pages**, **CMS blocks**, **product content** (descriptions
and SEO fields), and **category content** (the SEO text of category pages).

Compatible with **Magento 2.4** — Magento Open Source and Adobe Commerce,
self-hosted or on Adobe Commerce on cloud infrastructure (PaaS).

## Prerequisites

* **Magento 2.4.x**, Open Source or Adobe Commerce, served over **HTTPS** with
  a certificate from a publicly-trusted CA, and reachable from the **public
  internet**. Private hostnames, self-signed certificates, and plain HTTP are
  rejected.
* A dedicated **Integration** created for Semji — never a personal admin
  user's token. See [Step 1](#step-1-prepare-your-magento-store).
* The Integration's **API permissions (Resource Access)** granted as listed in
  [API permissions for the Integration](#api-permissions-for-the-integration).
* On **Magento 2.4.4 and above**: the setting **"Allow OAuth Access Tokens to
  be used as standalone Bearer tokens"** enabled — see
  [Step 1](#step-1-prepare-your-magento-store). Without it, every request
  returns `401` even with a valid token.
* If a firewall, WAF, or anti-bot protection (Fastly, Cloudflare, Akamai, …)
  sits in front of your store, it must **allow Semji's IP addresses** on the
  REST API path — see
  [Firewalls and IP allowlisting](#firewalls-and-ip-allowlisting).
* You are a **workspace owner** in Semji. The connection is shared with the
  whole workspace.

<Note>
  Availability of the Magento integration depends on your Semji plan. If the
  **Connect** button opens an upgrade dialog instead of the connection form,
  contact your account manager.
</Note>

<Note>
  **Adobe Commerce as a Cloud Service** (the newer SaaS offering that
  authenticates through Adobe IMS OAuth) is not supported. The connector
  authenticates exclusively with an Integration access token used as a Bearer
  credential.
</Note>

## Step 1 — Prepare your Magento store

<Steps>
  <Step title="Create a dedicated Integration">
    In the Magento admin, go to **System → Extensions → Integrations** and
    click **Add New Integration**. Give it a recognizable name (e.g.
    *Semji*).

    Do not reuse a personal admin account's token: an Integration can be
    scoped to exactly the permissions Semji needs, it survives admin account
    changes or offboarding, and it can be revoked independently without
    affecting any human user.
  </Step>

  <Step title="Grant the API permissions">
    On the Integration's **API** tab, set **Resource Access** to **Custom**
    and tick every checkbox listed in
    [API permissions for the Integration](#api-permissions-for-the-integration).

    Setting **Resource Access** to **All** also works if your security policy
    allows it — you can narrow it down later.
  </Step>

  <Step title="Activate and copy the Access Token">
    Save, then click **Activate** on the Integration's row and approve the
    permission summary. Magento displays four credentials — Semji only needs
    the **Access Token**. Copy it.
  </Step>

  <Step title="On Magento 2.4.4+ — allow tokens as standalone Bearer tokens">
    Since Magento 2.4.4, the REST Admin API rejects Integration access tokens
    used as bare Bearer tokens unless the store explicitly opts in. Enable:

    **Stores → Configuration → Services → OAuth → Consumer Settings →
    "Allow OAuth Access Tokens to be used as standalone Bearer tokens" → Yes**

    or via CLI:

    ```bash theme={null}
    bin/magento config:set oauth/consumer/enable_integration_as_bearer 1
    bin/magento cache:flush
    ```

    A cache flush may be needed for the change to take effect.
  </Step>
</Steps>

## API permissions for the Integration

On the Integration's **API** tab, with **Resource Access** set to **Custom**,
tick the following checkboxes:

| Checkbox to tick                             | ACL resource                             | Why Semji needs it                                                           | Required                           |
| -------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------- |
| Stores → Settings → **All Stores**           | `Magento_Backend::store`                 | List store views and their base URLs; validate the connection                | Always                             |
| Stores → Attributes → **Product**            | `Magento_Catalog::attributes_attributes` | Discover which product text fields exist before writing anything (read-only) | For product content                |
| Content → Elements → **Pages**               | `Magento_Cms::page`                      | Read and search CMS pages                                                    | For CMS pages                      |
| Content → Elements → Pages → **Save Page**   | `Magento_Cms::save`                      | Create and update CMS pages                                                  | For CMS pages                      |
| Content → Elements → **Blocks**              | `Magento_Cms::block`                     | Read, create and update CMS blocks                                           | For CMS blocks                     |
| Catalog → Inventory → **Products**           | `Magento_Catalog::products`              | Read and update product content                                              | For product content                |
| Catalog → Inventory → **Categories**         | `Magento_Catalog::categories`            | Read and update category content                                             | For category content               |
| Content → Elements → Pages → **Delete Page** | `Magento_Cms::page_delete`               | Delete CMS pages                                                             | Only if you enable the Delete tool |

<Warning>
  **The product-attributes checkbox lives under Stores, not under Catalog.**
  `Stores → Attributes → Product` and `Catalog → Inventory → Products` are two
  unrelated branches of the permission tree despite the similar names. Ticking
  the Catalog one without the Stores one breaks content-model discovery for
  products.
</Warning>

<Warning>
  **"Save Page" is a separate permission from "Pages".** Reading pages and
  writing pages are distinct ACL resources in Magento. Ticking the **Pages**
  parent checkbox selects its children automatically, but if you compose the
  selection checkbox by checkbox, do not skip **Save Page** — reads will work
  and every create or update will fail with a `401`.
</Warning>

<Note>
  If the permissions look right but requests still return `401`, re-open the
  Integration, re-select the resources, and **save again**. A partially saved
  custom selection can leave the permission state inconsistent, and a clean
  re-save repairs it.
</Note>

## Step 2 — Connect from Semji

<Steps>
  <Step title="Open the CMS integrations">
    In Semji, go to **Settings → Integrations**, open the **CMS** tab, and
    click **Connect** on the Magento row.
  </Step>

  <Step title="Enter your store's credentials">
    Fill in the two fields:

    * **Store URL** — the canonical HTTPS base URL of your store, e.g.
      `https://your-store.com`. Semji does not follow redirects, so use the
      exact URL your store resolves to (`www` vs non-`www` matters).
    * **Integration access token** — the Access Token copied in Step 1.

    Click **Next**. Semji tests the connection live by calling
    `GET /rest/all/V1/store/websites` on your store with the token.
  </Step>

  <Step title="Pick the Magento tools">
    Choose what AI agents can do on your store. Every tool is enabled by
    default; you can disable any of them:

    * **List store views** — read the store views and their base URLs.
    * **Describe content model** — inspect the writable fields of pages,
      blocks, products and categories.
    * **List contents** — browse and search CMS pages, blocks, products and
      categories.
    * **Read contents** — retrieve a page, block, product or category and its
      content.
    * **Create & update content** — create and update CMS pages and blocks,
      update product and category content.
    * **Delete content** — delete CMS pages and blocks.
  </Step>

  <Step title="Activate">
    Click **Activate**. The Magento row now shows as connected.
  </Step>
</Steps>

## What Semji can do once connected

| Content kind     | Read | Create | Update | Notes                                                                                   |
| ---------------- | ---- | ------ | ------ | --------------------------------------------------------------------------------------- |
| CMS pages        | ✓    | ✓      | ✓      | New pages are created **disabled (draft)**; publishing requires an explicit instruction |
| CMS blocks       | ✓    | ✓      | ✓      | Same draft-first behavior as pages                                                      |
| Product content  | ✓    | —      | ✓      | Description and SEO fields, written as product attributes                               |
| Category content | ✓    | —      | ✓      | The SEO text of category pages                                                          |

A few guarantees built into the connector:

* **Products and categories are never created or deleted** — Semji only
  updates the content fields of entities that already exist.
* **Product and category edits go live immediately** (Magento has no draft
  state for them), so agents show the exact field-by-field change and wait
  for your explicit validation before writing.
* **Page and block updates are lossless.** Magento's save endpoints replace
  the whole entity, so Semji reads the current entity, merges only the fields
  the agent changed, and writes the full payload back — anything the agent
  did not touch is preserved.
* **Deletion is never exposed to publishing agents.** Even with the Delete
  tool enabled, Semji's CMS Publisher agent is deliberately not given access
  to it.

### Store views

Magento content is **per store view**: the same page, product, or category
can carry different content on each store view.

* Agents read the store views first and target an **explicit store view**
  when you name a specific store, language, or locale.
* On multi-store installations, agents verify that the entry they are about
  to touch belongs to your workspace's website before writing, and refuse to
  modify content that belongs to another site hosted on the same Magento
  instance.
* Product and category writes never target Magento's `all` scope — a
  [known Magento issue](https://github.com/magento/magento2/issues/11324)
  can silently reassign website associations on writes scoped to `all`.

## Manage or disconnect

From **Settings → Integrations → CMS**, the Magento row offers:

* **Manage tools** — enable or disable each tool individually.
* **Disconnect** — remove the integration for the whole workspace.

## Firewalls and IP allowlisting

Semji's servers call your store's REST Admin API directly. If your store sits
behind Fastly, Cloudflare, or another WAF, you must allow those calls or the
connection will fail.

Semji's servers reach the internet through a fixed set of outbound IP addresses. If a firewall, WAF, or anti-bot protection (Cloudflare, Akamai, Sucuri, …) sits in front of your site, it can block Semji's requests — typically with a `403 Forbidden` — before they ever reach your CMS, even when your credentials are correct.

Allow the following Semji IP addresses:

```text theme={null}
63.34.75.122
63.35.78.179
54.228.104.165
18.200.156.37
34.248.117.83
52.213.28.177
```

Allow these addresses on the REST API path (`/rest/*`). On stores where the
edge layer rate-limits or challenges API traffic, exempt Semji's addresses
from those rules as well.

<Warning>
  A WAF answering with an HTML challenge or a `403` on `/rest/*` makes Semji
  report a security-layer error even though your token and permissions are
  correct. If the credentials look right, check the firewall first.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="&#x22;Magento rejected the request. Check the integration access token, that the Integration's API permissions (Resource Access) are granted, and, on Magento 2.4.4+, that 'Allow OAuth Access Tokens to be used as standalone Bearer tokens' is enabled.&#x22;">
    Magento returns the same `401` status for three different problems —
    check them in order:

    1. **The token value is wrong** — re-copy the Access Token from the
       Integration (System → Extensions → Integrations). Note that
       re-creating or re-authorizing an Integration generates a new token.
    2. **On Magento 2.4.4+, the Bearer setting is off** — enable *"Allow
       OAuth Access Tokens to be used as standalone Bearer tokens"* (see
       [Step 1](#step-1-prepare-your-magento-store)) and flush the cache.
    3. **The Integration lacks API permissions** — Magento answers `401`
       with *"The consumer isn't authorized to access %resources"* naming
       the missing ACL resource. Grant every checkbox in
       [API permissions for the Integration](#api-permissions-for-the-integration),
       save again, and retry.

    A quick way to tell cases 1–2 apart from case 3: if **some** REST
    endpoints respond with the token while others return `401`, the token
    and the Bearer setting are fine — the remaining `401`s are missing
    permissions.
  </Accordion>

  <Accordion title="&#x22;The Magento REST API was not found at this URL.&#x22;">
    `GET /rest/all/V1/store/websites` returned a `404`. Frequent causes:

    * The **Store URL is wrong** or points to a specific store-view path.
      Enter the bare base URL of the store.
    * **The URL redirects.** Semji follows no redirects: if
      `https://example.com` redirects to `https://www.example.com`, enter
      the `www` URL.
    * A reverse proxy in front of Magento **strips or blocks the `/rest`
      path**.
  </Accordion>

  <Accordion title="&#x22;Your store's security layer blocked our request.&#x22;">
    The response came from a WAF or anti-bot layer (a `403`, or a non-JSON
    challenge page) instead of Magento. Allow Semji's IP addresses on
    `/rest/*` — see
    [Firewalls and IP allowlisting](#firewalls-and-ip-allowlisting).
  </Accordion>

  <Accordion title="&#x22;The store cannot be reached.&#x22;">
    * **DNS failure or host down.**
    * **The store is too slow** — responses must arrive within 10 seconds.
    * **The URL points to a private or reserved address** — localhost and
      private-network hosts are rejected; the store must be publicly
      reachable.
  </Accordion>

  <Accordion title="An agent reports an authentication or permission error on one action">
    The token authenticates, but the Integration lacks the ACL resource for
    that specific action — for example, pages can be read but not saved
    (missing **Save Page**), or products cannot be listed (missing
    **Catalog → Inventory → Products**). Grant the corresponding checkbox
    from
    [API permissions for the Integration](#api-permissions-for-the-integration)
    and save the Integration again.
  </Accordion>

  <Accordion title="A product or category update went live immediately">
    That is Magento's behavior, not a bug: products and categories have no
    draft state, so every write is live on the storefront. Semji's agents
    show the exact diff and require your explicit validation before each
    product or category write for this reason. CMS pages and blocks, in
    contrast, are created as drafts.
  </Accordion>

  <Accordion title="URL validation errors before submitting">
    * *"Please enter a valid URL."* — the value does not parse as a URL.
    * *"The store URL must start with https\://."* — HTTP stores cannot be
      connected.
    * *"The store URL points to a private or reserved address, which is not
      allowed."* — the store must be publicly reachable.
  </Accordion>
</AccordionGroup>

## Related

* [Sync drafts to your CMS](/guides/sync-drafts-to-cms) — API-based
  publishing flow, if you prefer to drive the sync yourself.
