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

# Drupal integration: connect your site to publish from Semji

> Connect Drupal to publish from Semji without copy-pasting. You decide what agents can read, create, or modify.

## At a glance

* **What you can do**: give Semji's agents controlled access to your Drupal content.
* **Who it's for**: workspace owners and Drupal administrators.
* **Compatibility**: Drupal 8.7 and newer, the version that brought JSON:API into Drupal core.

## Prerequisites

* Drupal 8.7 or newer, live, public, and served over HTTPS.
* The JSON:API and HTTP Basic Authentication (basic\_auth) modules enabled. Both ship with Drupal.
* JSON:API set to read-write: check "Accept all JSON:API create, read, update, and delete operations" under `/admin/config/services/jsonapi`. It's read-only by default, which makes it the most common blocker.
* A Drupal account dedicated to Semji, with the permissions listed in [Permissions for the API account](#permissions-for-the-api-account). A plain editor role is not enough, see that section for why.
* To let agents write meta descriptions: the Metatag module, plus a Meta tags field on each content type concerned. See [Meta descriptions](#meta-descriptions).
* If a firewall, WAF, or anti-bot protection (Cloudflare, Akamai, Sucuri, …) sits in front of your site, it must allow Semji's IP addresses. 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 Drupal integration depends on your Semji plan. If the Connect button opens an upgrade dialog instead of the connection form, contact your account manager.
</Note>

## How to connect your Drupal site

<Steps>
  <Step title="Prepare your Drupal site">
    Three settings to handle on the Drupal side before connecting Semji.

    **Enable the modules.** On the modules page (Extend menu, /admin/modules), enable JSON:API and HTTP Basic Authentication. Both come with Drupal.

    **Allow writing.** In Configuration → Web services → JSON:API (/admin/config/services/jsonapi), select "Accept all JSON:API create, read, update, and delete operations". Without this, Semji can read your content but cannot create or edit it.

    **Create a role and an account for Semji.** Under People → Roles, create a role (e.g. Semji API) and grant it the permissions listed in [Permissions for the API account](#permissions-for-the-api-account). Then, under People (/admin/people), create a dedicated account, e.g. semji-api, with a strong password, and assign it that role.

    Do not reuse a plain editor role: it lacks the permission Semji needs to set the publication status, and every write fails with a `403`.

    **Add a Meta tags field, only if you want meta descriptions.** See [Meta descriptions](#meta-descriptions) for the full procedure.

    <Tip>
      If publishing fails, the first setting to check is almost always JSON:API's write permission.
    </Tip>
  </Step>

  <Step title="Connect from Semji">
    You must be a workspace owner, since the connection applies to the whole team. In Semji, open Settings → Integrations, go to the CMS tab, and click Connect on the Drupal row.

    <video autoPlay muted loop playsInline src="https://mintcdn.com/semji/ZF6m599EYafA5y4i/images/help-center/connect-your-tools/cms-publisher/01-cms-integration.mp4?fit=max&auto=format&n=ZF6m599EYafA5y4i&q=85&s=901ef6b3c1b91a4cb6762427eaaade8c" title="CMS Integration" data-path="images/help-center/connect-your-tools/cms-publisher/01-cms-integration.mp4" />

    Fill in the three fields:

    * **Site URL**: your site's exact address over HTTPS, e.g. `https://your-site.com`. Enter the address your site actually uses: if it switches from example.com to [www.example.com](http://www.example.com), enter the www version. Semji does not follow redirects.
    * **Username**: the Drupal login of the API account created in step 1.
    * **Password**: that account's password.

          <img src="https://mintcdn.com/semji/ql0fCIIUu6X2284g/images/help-center/connect-your-tools/integration-drupal/01-connect-drupal.jpg?fit=max&auto=format&n=ql0fCIIUu6X2284g&q=85&s=660ef0198fab3b1d3e745ff8ed8c1a54" alt="connect drupal" width="670" height="389" data-path="images/help-center/connect-your-tools/integration-drupal/01-connect-drupal.jpg" />

    Click Next. Semji tests the connection live by calling `GET /jsonapi` on your site and verifying that Drupal authenticates the account.
  </Step>

  <Step title="Pick the Drupal tools">
    Choose what AI agents can do on your site. All three groups are enabled by default:

    * **Read**: browse, read, and inspect the site's content and structure.
    * **Write**: create and update content.
    * **Delete**: delete content. Note that this action is irreversible.
  </Step>

  <Step title="Save">
    Click Save. The Drupal row now shows as connected.
  </Step>
</Steps>

## Permissions for the API account

Grant these to the role you created for Semji. Replace `article` with each content type agents will work on.

| Permission | Why Semji needs it | Required |
| - | - | - |
| `access content` | Read published content | Always |
| `create article content` | Create new content | To create |
| `edit any article content` | Update content the account did not author | To update |
| `use text format basic_html` | Write the body in the text format Semji targets | Always |
| `administer nodes` | Set the publication status (draft vs published) | On content types without Content Moderation |
| Workflow transition permissions | Move content between moderation states | On content types with Content Moderation |
| `create terms in tags` | Match or create tags in the `tags` vocabulary | If agents attach tags |
| Paragraphs type permissions | Create the paragraphs of a component-based layout | If your site uses Paragraphs |
| `delete any article content` | Delete content | Only if you enable the Delete tool |
| `administer node fields` | Read the field definitions of your content types | Optional, see below |

<Warning>
  **`administer nodes` is required on content types that do not use Content Moderation.** Semji always states the publication status explicitly, so content is never published by accident, and Drupal reserves writing the `status` field to that permission. Without it, every create and update fails with "The current user is not allowed to POST the selected field (status). The 'administer nodes' permission is required."

  On a content type governed by Content Moderation, Semji writes the moderation state instead, so `administer nodes` is not needed. Grant the transition permissions of your workflow instead.
</Warning>

### About `administer node fields`

This one is optional but recommended. With it, Semji reads your content types' field definitions directly and knows exactly which field holds what. Without it, Semji falls back to inspecting an existing piece of content to infer the structure. That works, but it is less precise and needs at least one existing item per content type.

Drupal flags this permission as restricted, because the same permission also allows adding and deleting fields through the admin UI. If your security policy rules that out, leave it off: the integration works without it.

## Meta descriptions

Drupal core has no meta description field. Semji writes meta descriptions through the [Metatag](https://www.drupal.org/project/metatag) contributed module, which most Drupal SEO setups already use.

<Steps>
  <Step title="Install and enable Metatag">
    Install the module the way you normally install contributed modules, then enable it under Extend.
  </Step>

  <Step title="Add a Meta tags field to each content type">
    Go to Structure → Content types → your type → Manage fields → Create a new field, and pick the Meta tags field type. Any label and machine name work: Semji identifies the field by its type, not its name.
  </Step>
</Steps>

Once the field exists, pass the meta description to an agent like any other instruction ("write the meta description too"). Semji formats and stores it for you. On an update it merges into the tags already on the item, so a meta title you wrote by hand is preserved.

<Note>
  If a content type has no Meta tags field, agents write the content normally and tell you the meta description could not be saved. They never fall back to pasting it into the body.
</Note>

## What Semji can do once connected

| Tool group | What it does |
| - | - |
| Read | List content types, spot their fields and text formats, list and read content as it's stored, for faithful edits |
| Write | Create and update content. New content is created as a draft, unless you explicitly ask an agent to publish. Existing tags are reused, new ones are created. Paragraphs-based layouts are supported |
| Delete | Permanently delete a piece of content. The agent always asks for confirmation first |

### Content defaults

Out of the box, Semji targets the `article` content type with the `basic_html` text format. On sites using Content Moderation, Semji writes the `published` and `draft` moderation states instead of the raw status field. Contact Semji support if your site needs different defaults (another content type, text format, or custom moderation state names).

## Manage or disconnect

From Settings → Integrations → CMS, the Drupal row offers:

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

## Firewalls and IP allowlisting

Semji calls your site's JSON:API directly. If a firewall or protection like Cloudflare sits in front of your Drupal, it must let these calls through, or the connection fails.

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
```

On Cloudflare, create a WAF custom rule with the Skip action, matching requests where the source IP is one of the addresses above and the path starts with `/jsonapi/`.

<Warning>
  A firewall block looks just like a credentials error. When a protection layer answers "403 Forbidden" on /jsonapi, Semji shows an invalid-credentials error even though your username and password are correct. If you're sure of the credentials, check the firewall first.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Invalid Drupal credentials. Check the username and the password.">
    Drupal refused the connection. Possible causes: the username or password is wrong, the basic\_auth module isn't enabled (Drupal then treats the request as an anonymous visitor), or a firewall is blocking the request before it reaches Drupal.
  </Accordion>

  <Accordion title="Could not connect to the Drupal site. Check the credentials, the site URL, and that the JSON:API and Basic Auth modules are enabled.">
    Semji couldn't reach your site. The most common causes:

    * The JSON:API module is disabled: /jsonapi returns a 404.
    * The address redirects. Semji does not follow redirects, so enter the final address, for example the www version.
    * The site is unreachable: a DNS problem, host down, or a non-public site.
    * A firewall shows an anti-bot verification page that Semji can't get past.
    * The site responds too slowly: the response must arrive within 10 seconds.
  </Accordion>

  <Accordion title="Drupal JSON:API is configured to accept only read operations.">
    Publishing fails with a read-only error. An administrator must enable "Accept all JSON:API create, read, update, and delete operations" under /admin/config/services/jsonapi.
  </Accordion>

  <Accordion title="Drupal authentication or permission error: the API account cannot create or update this content.">
    An agent reports a permission error. The account created for Semji lacks the needed rights on this content type. On Paragraphs sites, also check its Paragraphs permissions (Paragraphs Type Permissions for the API account).
  </Accordion>

  <Accordion title="Every write fails, but the credentials and JSON:API settings are correct">
    Check whether the account has `administer nodes`. Drupal reserves writing the `status` field to that permission, and Semji always states the publication status explicitly, so an account without it fails on every create and update, even though reading works fine and the connection test passes. See [Permissions for the API account](#permissions-for-the-api-account).
  </Accordion>

  <Accordion title="The connection test fails while the site looks fine in a browser">
    If your site is in maintenance mode, Drupal answers `503` on `/jsonapi` for every account without the "Use the site in maintenance mode" permission, which the API account normally does not have. You can browse the site yourself because your admin session bypasses it. Turn maintenance mode off under Configuration → Development → Maintenance mode, or grant that permission to the Semji role.
  </Accordion>

  <Accordion title="An agent says the meta description was not saved">
    Two distinct cases:

    * No meta description field on this content type: install Metatag and add a Meta tags field, as described in [Meta descriptions](#meta-descriptions).
    * Drupal accepted the write but stored nothing: Semji could not read your field definitions and guessed the wrong format. Grant `administer node fields` to the API account, or set that one meta description by hand.

    In both cases the rest of the content is written normally.
  </Accordion>

  <Accordion title="Errors shown before you even submit the form">
    * "Please enter a valid URL." The text you entered isn't a web address.
    * "The site URL must start with https\://." HTTP sites cannot be connected.
    * "The site URL points to a private or reserved address, which is not allowed." Local or internal sites are rejected, the site must be public.
  </Accordion>
</AccordionGroup>

## Related

* [CMS Publisher: publish your content to your CMS without leaving Semji](/en/connect-your-tools/cms-publisher)
* [Sync drafts to your CMS](/guides/sync-drafts-to-cms): API-based publishing flow, if you prefer to drive the sync yourself.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.