---
url: 'https://dxpr.com/nl/hc/documentatie/dxpr-builder-leren/ai/api-referentie'
title: 'AI-API-referentie | DXPR'
author:
  name: Jurriaan
  url: 'https://dxpr.com/users/jurriaan'
date: '2026-10-24T02:33:08+00:00'
updated: '2026-10-24T17:19:22+00:00'
copyright: 'Copyright DXPR. All rights reserved.'
type: article
summary: |-
  DXPR Builder biedt drie AI-routes aan. De browser
  roept ze aan en de controllers proxyen het verzoek
  via de Drupal AI-module naar de DXPR-provider
  (ai_provider_dxpr), zodat de API-sleutel nooit in
  de browser komt. Routes zijn gedefinieerd in
  dxpr_builder.routing.yml; het gedrag hieronder komt
  uit src/Controller/AiChatController.php en
  src/Controller/AiImageController.php.
tags:
  - 'Architecture and APIs'
image: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
published: true
og:
  site_name: DXPR
  updated_time: '2026-10-24T17:19:22+0000'
  'image:alt': 'DXPR, powered by Drupal: AI-powered Drupal for marketers.'
schema:
  '@context': 'https://schema.org'
  '@graph':
    -
      mainEntity: {  }
    -
      '@type': TechArticle
      headline: AI-API-referentie
      description: |-
        DXPR Builder biedt drie AI-routes aan. De browser
        roept ze aan en de controllers proxyen het verzoek
        via de Drupal AI-module naar de DXPR-provider
        (ai_provider_dxpr), zodat de API-sleutel nooit in
        de browser komt. Routes zijn gedefinieerd in
        dxpr_builder.routing.yml; het gedrag hieronder komt
        uit src/Controller/AiChatController.php en
        src/Controller/AiImageController.php.
      image:
        '@type': ImageObject
        url: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
        width: '1200'
        height: '630'
      datePublished: '2026-10-24T02:33:08+0000'
      dateModified: '2026-10-24T17:19:22+0000'
      author:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      mainEntityOfPage: 'https://dxpr.com/nl/hc/documentatie/dxpr-builder-leren/ai/api-referentie'
      articleSection: 'Architectuur en API’s'
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/nl/hc/documentatie/dxpr-builder-leren/ai/api-referentie'
      description: |-
        DXPR Builder biedt drie AI-routes aan. De browser
        roept ze aan en de controllers proxyen het verzoek
        via de Drupal AI-module naar de DXPR-provider
        (ai_provider_dxpr), zodat de API-sleutel nooit in
        de browser komt. Routes zijn gedefinieerd in
        dxpr_builder.routing.yml; het gedrag hieronder komt
        uit src/Controller/AiChatController.php en
        src/Controller/AiImageController.php.
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: Home
            item: 'https://dxpr.com/nl'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
      inLanguage: nl
---
[Helpcentrum](/nl/hc)/[Documentatie](/nl/hc/documentatie) /[DXPR Builder leren](/nl/hc/documentation/learn-dxpr-builder) /[Uitbreiden](/nl/hc/documentation/learn-dxpr-builder/extend) /[Architectuur en API’s](/nl/hc/documentation/learn-dxpr-builder/extend/architecture) # AI-API-referentie.

 DXPR Builder lerenUitbreidenArchitectuur en API’s

   ## In deze gids

 Gerelateerde gidsen

- [AI-modellen en providers](/nl/hc/documentatie/dxpr-builder-leren/ai/modellen-en-providers)
- [AI-configuratie](/nl/hc/documentatie/dxpr-builder-leren/ai/configuratie)
- [AI-problemen oplossen](/nl/hc/documentatie/dxpr-builder-leren/ai/probleemoplossing)

DXPR Builder biedt drie AI-routes aan. De browser roept ze aan en de controllers proxyen het verzoek via de Drupal AI-module naar de DXPR-provider (`ai_provider_dxpr`), zodat de API-sleutel nooit in de browser komt. Routes zijn gedefinieerd in `dxpr_builder.routing.yml`; het gedrag hieronder komt uit `src/Controller/AiChatController.php` en `src/Controller/AiImageController.php`.

## Toegangsvereisten (alle drie routes)

| Vereiste | Bron |
|---|---|
| HTTP-methode `POST` | `methods: [POST]` in de route |
| Rechten `edit with dxpr builder` | `_permission` |
| Factureerbare gebruiker (geldige licentieplek) | `_dxpr_builder_billable_user`, gecontroleerd door `DxprBuilderBillableUserAccessCheck` |
| CSRF-token in de `token`-queryparameter | `_csrf_token: 'TRUE'` |
| Ingelogde Drupal-sessiecookie | Drupal-toegangscontroles draaien per gebruiker |

Het token is het route-CSRF-token van Drupal voor het routepad. DXPR Builder genereert het serverside en bet het in in `drupalSettings.dxprBuilder.aiAgent`als `endpointUrl`, `imageEndpointUrl` en `imageEditEndpointUrl` (zie `DxprBuilderFormatter`). Lees een van die waarden uit van een pagina waar de editor is geladen om een werkende URL te krijgen. Een mislukte toegangscontrole geeft het standaard `403`-antwoord van Drupal.

De controllers instantiëren altijd de `dxpr`-provider; de provider die is ingesteld op `/admin/config/ai/settings` wordt niet gebruikt.

## Chat

`POST /dxpr_builder/ajax/ai/chat?token=...`

Gebruikt door tekstcommando's, paginaopstelling en promptsuggesties. De controller leest een JSON-body en roept `$provider->chat()` aan.

### Aanvraagbody

| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
| `messages` | array van `{role, content}` | ja | `role` is `system`, `user` of `assistant` |
| `model` | string | nee | Standaard `kavya-m1`. Moet op de lijst Allowed models van de provider staan |
| `stream` | boolean | nee | Standaard `true` |
| `prediction` | object | nee | Wordt doorgegeven, bijvoorbeeld `{"type":"content","content":"<p>...</p>"}` |
| `providers` | string | nee | Komma-gescheiden provider-ID's, bijvoorbeeld `openai,mistral` |
| `allowed_html_tags` | string | nee | Wordt doorgegeven; de builder stuurt `Bootstrap 5 HTML` |
| `allowed_html_classes` | string | nee | Wordt doorgegeven; de builder stuurt `Bootstrap 5 Classes` |
| `web_search` | boolean | nee | Alleen `false` wordt doorgestuurd |
| `response_format` | object | nee | Wordt doorgegeven, bijvoorbeeld een `json_schema`-object |

De controller voegt altijd `jsonrpc: false` toe aan de providerconfiguratie. Vóór de aanroep voegt hij de domeinen uit **AI Output Filtering &gt; Allowed domains** samen in het hostnaamfilter van de AI-module voor de duur van het verzoek (`*` schakelt het filter om naar volledig vertrouwen).

### Antwoord

Gestreamd (`stream` true, de standaard): `200`, `Content-Type: text/event-stream`. Elke event is `data: {json}` gevolgd door een lege regel, en de stream eindigt met `data: [DONE]`.

```text
data: {"choices":[{"delta":{"content":"Hello"}}],"id":"...","model":"kavya-m1","usage":{...}}

data: [DONE]

```

`id`, `object`, `created`, `model`, `original_model` en `usage` worden gekopieerd uit de ruwe chunk van de provider wanneer aanwezig.

Niet-gestreamd (`stream` false): `200`, `application/json`:

```json
{"choices":[{"message":{"role":"assistant","content":"..."}}]}

```

### Fouten

| Status | Body |
|---|---|
| `400` | Platte tekst `Invalid request: messages required` |
| `403` | `{"error":{"code":"model_not_allowed","message":"The selected model is not allowed. Please refresh the page to update your model options."}}` wanneer `ai_provider_dxpr` is geïnstalleerd en `model` niet op zijn lijst Allowed models staat |
| `500` | `{"error":{"message":"The request could not be completed."}}` (details in het `dxpr_builder`-logkanaal) |

### Voorbeeld

```js
const url = drupalSettings.dxprBuilder.aiAgent.endpointUrl;
const res = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "kavya-m1",
    stream: false,
    messages: [
      { role: "system", content: "You are a copywriter." },
      { role: "user", content: "Shorten: <p>Our team ...</p>" }
    ]
  })
});
const data = await res.json();
console.log(data.choices[0].message.content);

```

## Afbeeldingsgeneratie

`POST /dxpr_builder/ajax/ai/image?token=...`

Roept `$provider->textToImage()` aan.

### Aanvraagbody

| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
| `prompt` | string | ja | Tekstbeschrijving van de afbeelding |
| `model` | string | nee | Standaard `kavya-image` |
| `size` | string | nee | De builder stuurt `1024x1024`, `1536x1024` of `1024x1536`; weggelaten voor Auto |
| `quality` | string | nee | Ongewijzigd doorgegeven aan de provider |
| `background` | string | nee | Ongewijzigd doorgegeven aan de provider |

### Antwoord

`200`, `application/json`. Alleen de eerste afbeelding wordt teruggegeven, base64-gecodeerd. De DXPR-provider vraagt `webp`-output aan.

```json
{"data":[{"b64_json":"UklGRi..."}]}

```

### Fouten

| Status | Body |
|---|---|
| `400` | `{"error":{"message":"Invalid request: prompt required"}}` |
| `500` | `{"error":{"message":"No image was generated"}}` |
| `500` | `{"error":{"message":"Image generation failed. Please try again."}}` |

### Voorbeeld

```bash
curl -X POST "https://example.com/dxpr_builder/ajax/ai/image?token=TOKEN" \
  -H "Content-Type: application/json" \
  -H "Cookie: SESSxxx=..." \
  -d '{"prompt":"Flat illustration of a rocket","size":"1536x1024"}'

```

## Afbeeldingsbewerking

`POST /dxpr_builder/ajax/ai/image/edit?token=...`

Roept `$provider->imageToImage()` aan met de geüploade afbeelding en de prompt.

### Aanvraagbody

| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
| `prompt` | string | ja | Bewerkingsinstructie |
| `image` | string | ja | Base64-afbeeldingsdata zonder `data:`-prefix; strikte decodering |
| `mimeType` | string | nee | Standaard `image/png`; het subtype wordt de bestandsextensie |
| `model` | string | nee | Standaard `kavya-image` |
| `size`, `quality`, `background` | string | nee | Zoals bij afbeeldingsgeneratie |

### Antwoord

Zelfde vorm als afbeeldingsgeneratie: `{"data":[{"b64_json":"..."}]}`.

### Fouten

| Status | Body |
|---|---|
| `400` | `{"error":{"message":"Invalid request: prompt and image required"}}` |
| `400` | `{"error":{"message":"Invalid image data: base64 decode failed"}}` |
| `500` | `{"error":{"message":"No image was generated"}}` |
| `500` | `{"error":{"message":"Image editing failed. Please try again."}}` |

### Voorbeeld

```js
const url = drupalSettings.dxprBuilder.aiAgent.imageEditEndpointUrl;
const res = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    prompt: "Remove the background",
    image: base64String,
    mimeType: "image/jpeg"
  })
});
const { data } = await res.json();

```

## Een gegenereerde afbeelding opslaan

De routes geven alleen afbeeldingsbytes terug. De builder converteert `b64_json` naar een `webp`-bestand en uploadt het naar `POST /dxpr_builder/ajax/file_upload`(`drupalSettings.dxprBuilder.fileUploadUrl`, formulierveld `upload[]`), dat antwoordt met de `url` en `fid` van het bestand. De prompt wordt de bestandsnaam (eerste 80 tekens) en het alt-attribuut.

## Wat nu?

- [Modellen en providers](/nl/hc/documentatie/dxpr-builder-leren/ai/modellen-en-providers)
- [AI-configuratie](/nl/hc/documentatie/dxpr-builder-leren/ai/configuratie)
- [AI-problemen oplossen](/nl/hc/documentatie/dxpr-builder-leren/ai/probleemoplossing)