---
url: 'https://dxpr.com/ko/hc/documentation/learn-dxpr-builder/reference/api-endpoints'
title: 'API 엔드포인트 | DXPR'
author:
  name: Jurriaan
  url: 'https://dxpr.com/users/jurriaan'
date: '2026-10-24T14:18:00+00:00'
updated: '2026-10-24T17:19:22+00:00'
copyright: 'Copyright DXPR. All rights reserved.'
type: article
summary: |-
  이 페이지에서는 DXPR Builder가 dxpr_builder.routing.yml에 등록하는 모든 라우트를 HTTP 메서드, 접근 요구 사항, 요청 매개변수, 컨트롤러에 구현된 응답 형태와 함께 나열합니다. 에디터의 JavaScript가 AJAX 엔드포인트의 의도된 클라이언트입니다. 이 페이지의 어떤 내용도 안정적인 공개 API가 아니며, 매개변수 이름은 릴리스마다 변경될 수 있습니다.
  접근 요구 사항
  라우트는 세 가지 요구 사항을 사용합니다. 하나의 라우트에서 여러 개를 조합할 수 있습니다.
tags:
  - 'Configuration and API'
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: 'API 엔드포인트'
      description: |-
        이 페이지에서는 DXPR Builder가 dxpr_builder.routing.yml에 등록하는 모든 라우트를 HTTP 메서드, 접근 요구 사항, 요청 매개변수, 컨트롤러에 구현된 응답 형태와 함께 나열합니다. 에디터의 JavaScript가 AJAX 엔드포인트의 의도된 클라이언트입니다. 이 페이지의 어떤 내용도 안정적인 공개 API가 아니며, 매개변수 이름은 릴리스마다 변경될 수 있습니다.
        접근 요구 사항
        라우트는 세 가지 요구 사항을 사용합니다. 하나의 라우트에서 여러 개를 조합할 수 있습니다.
      image:
        '@type': ImageObject
        url: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
        width: '1200'
        height: '630'
      datePublished: '2026-10-24T14:18:00+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/ko/hc/documentation/learn-dxpr-builder/reference/api-endpoints'
      articleSection: '설정과 API'
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/ko/hc/documentation/learn-dxpr-builder/reference/api-endpoints'
      description: |-
        이 페이지에서는 DXPR Builder가 dxpr_builder.routing.yml에 등록하는 모든 라우트를 HTTP 메서드, 접근 요구 사항, 요청 매개변수, 컨트롤러에 구현된 응답 형태와 함께 나열합니다. 에디터의 JavaScript가 AJAX 엔드포인트의 의도된 클라이언트입니다. 이 페이지의 어떤 내용도 안정적인 공개 API가 아니며, 매개변수 이름은 릴리스마다 변경될 수 있습니다.
        접근 요구 사항
        라우트는 세 가지 요구 사항을 사용합니다. 하나의 라우트에서 여러 개를 조합할 수 있습니다.
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: 홈
            item: 'https://dxpr.com/ko'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
      inLanguage: ko
---
[도움말 센터](/ko/node/75)/[문서](/ko/hc/documentation) /[DXPR Builder 배우기](/ko/hc/documentation/learn-dxpr-builder) /[참조](/ko/hc/documentation/learn-dxpr-builder/reference) /[설정과 API](/ko/hc/documentation/learn-dxpr-builder/reference/config-and-api) # API 엔드포인트.

 DXPR Builder 배우기참조설정과 API

   ## 이 가이드의 내용

 관련 가이드

- [구성 참조](/ko/hc/documentation/learn-dxpr-builder/reference/config-reference)
- [API 참조](/ko/hc/documentation/learn-dxpr-builder/development/api)
- [후크 API 참조](/ko/hc/documentation/learn-dxpr-builder/development/hooks-api)

이 페이지에서는 DXPR Builder가 `dxpr_builder.routing.yml`에 등록하는 모든 라우트를 HTTP 메서드, 접근 요구 사항, 요청 매개변수, 컨트롤러에 구현된 응답 형태와 함께 나열합니다. 에디터의 JavaScript가 AJAX 엔드포인트의 의도된 클라이언트입니다. 이 페이지의 어떤 내용도 안정적인 공개 API가 아니며, 매개변수 이름은 릴리스마다 변경될 수 있습니다.

## 접근 요구 사항

라우트는 세 가지 요구 사항을 사용합니다. 하나의 라우트에서 여러 개를 조합할 수 있습니다.

| 요구 사항 | 의미 |
|---|---|
| `_permission` | 사용자에게 지정된 Drupal 권한이 필요합니다. DXPR Builder는 `administer dxpr builder configuration`, `edit with dxpr builder`, `administer dxpr_builder_profile`를 `dxpr_builder.permissions.yml`에 정의합니다. `view media`와 `administer site configuration`은 코어에서 제공합니다. |
| `_csrf_token` | 요청에는 `token` 쿼리 매개변수에 유효한 CSRF 토큰이 포함되어야 합니다. 주요 AJAX 핸들러의 경우 에디터는 토큰이 포함된 URL을 `/dxpr_builder/csrf`(또는 `dxpr_builder_csrf` 작업)에서 가져옵니다. 다른 라우트의 경우 필드 포매터가 토큰이 포함된 URL을 `drupalSettings.dxprBuilder`에 넣습니다(예: `fileUploadUrl`, `entityLinkSuggestionsUrl`, `userSettingsUrl` 및 `aiAgent.endpointUrl`. |
| `_dxpr_builder_billable_user` | 사용자는 아래에 정의된 billable user여야 합니다. |

### 'billable user'의 의미

`DxprBuilderBillableUserAccessCheck`는 `DxprBuilderLicenseService::isBillableUser()`가 현재 계정에 대해 true를 반환하면 접근을 허용합니다. 해당 메서드는 차단된 계정과 `dxpr_user_is_disavowed` 필드가 설정된 계정(관리자가 User Licenses 페이지에서 편집에서 사용자를 제외함)에 대해 false를 반환합니다. 그 외에는 사용자 1과 `edit with dxpr builder` 권한을 보유한 모든 계정에 대해 true를 반환합니다. 간단히 말해, billable user는 DXPR Builder로 편집할 수 있는 활성 상태의 제외되지 않은 계정이며, 라이선스 서비스는 이러한 계정을 제품 키에 대해 집계합니다.

### HTTP 메서드

라우트에서 `methods`를 선언하면 해당 메서드만 라우팅됩니다. 선언하지 않으면 라우트는 모든 메서드를 허용합니다(Drupal의 `MethodFilter` 메서드를 선언한 라우트만 필터링합니다). 아래 표에서는 소스에서 확인할 수 있는 경우 에디터의 JavaScript가 실제로 사용하는 메서드를 명시합니다.

## 에디터 AJAX 엔드포인트

### CSRF 토큰 URL

|  |  |
|---|---|
| 경로 | `/dxpr_builder/csrf` |
| 라우트 | `dxpr_builder.csrf_refresh` |
| 메서드 | 선언되지 않음(모든 메서드). 에디터는 GET을 전송합니다(`backend-connect.js`, `fetchCsrfTokenUrl()`). |
| 요구 사항 | Billable user |
| 컨트롤러 | `AjaxController::ajaxRefresh()` |

요청에는 `X-Requested-With: XMLHttpRequest` 헤더가 포함되어야 합니다. 없으면 컨트롤러는 `{"error": "Invalid request"}` JSON 본문과 함께 HTTP 403을 반환합니다.

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `enterprise` | 쿼리 문자열 | 선택 | 이 옵션을 `true`로 설정하고 `dxpr_builder_e` 모듈이 설치된 경우 토큰은 `dxpr_builder_e.ajax_callback` 라우트용으로 대신 생성됩니다. 해당 모듈 없이 `true`로 설정되면 컨트롤러가 예외를 발생시킵니다. |

응답: 주요 AJAX 핸들러의 URL과 `token` 쿼리 매개변수가 포함된 JSON 문자열입니다. URL은 사이트 루트에서의 경로입니다(기본 경로 포함, 호스트 없음). JavaScript는 모든 빌더 작업을 이 URL에 POST로 전송합니다.

### 주요 AJAX 핸들러

|  |  |
|---|---|
| 경로 | `/dxpr_builder/ajax` |
| 라우트 | `dxpr_builder.ajax_callback` |
| 메서드 | 선언되지 않음(모든 메서드). 컨트롤러는 모든 매개변수를 POST 본문에서 읽으며, 에디터는 POST를 전송합니다. |
| 요구 사항 | Billable user, CSRF token |
| 컨트롤러 | `AjaxController::ajaxCallback()` |

POST 본문 필드 `action`이 작업을 선택합니다. 모든 작업과 매개변수는 [주요 AJAX 핸들러 작업](#main-ajax-handler-operations)에 나열되어 있습니다. `action`이 누락되거나 알 수 없으면 컨트롤러는 명령이 없는 빈 Drupal `AjaxResponse`를 반환합니다. billable user 상태를 다시 확인하는 대부분의 작업은 해당 확인이 실패하면 동일한 빈 응답을 반환합니다. 두 가지 예외는 표에 명시되어 있습니다.

### AI 채팅

|  |  |
|---|---|
| 경로 | `/dxpr_builder/ajax/ai/chat` |
| 라우트 | `dxpr_builder.ai_chat` |
| 메서드 | POST |
| 요구 사항 | `edit with dxpr builder`, billable user, CSRF token |
| 컨트롤러 | `AiChatController::chat()` |

요청 본문은 JSON입니다. 컨트롤러는 요청을 Drupal `ai` 모듈의 `dxpr` 제공업체에 프록시합니다. 브라우저에 API 키가 도달하지 않습니다. 호출 전에 `ai_output_allowed_domains` 설정의 도메인을 `ai` 모듈의 호스트 이름 필터에 병합합니다(해당 서비스가 있는 경우). `*` 값은 대신 필터를 완전 신뢰로 설정합니다. 필터는 이후에 복원됩니다.

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `messages` | JSON 본문 | 필수 | 객체 배열입니다. 각 객체에는 `role`과 `content`가 있습니다. |
| `stream` | JSON 본문 | 선택 | 불리언, 기본값: `true`. |
| `model` | JSON 본문 | 선택 | 기본값: `kavya-m1`. |
| `prediction` | JSON 본문 | 선택 | 배열로 제공업체 구성에 전달됩니다. |
| `providers` | JSON 본문 | 선택 | 제공업체 구성에 그대로 전달됩니다. |
| `allowed_html_tags` | JSON 본문 | 선택 | 제공업체 구성에 그대로 전달됩니다. |
| `allowed_html_classes` | JSON 본문 | 선택 | 제공업체 구성에 그대로 전달됩니다. |
| `web_search` | JSON 본문 | 선택 | 다음 값만 전달되며 다른 값은 무시됩니다: `false`. |
| `response_format` | JSON 본문 | 선택 | 배열로 제공업체 구성에 전달됩니다. |

응답:

| 사례 | 상태 | 본문 |
|---|---|---|
| 스트리밍(`stream`이 true이며 제공업체가 스트리밍하는 경우) | 200, `Content-Type: text/event-stream` | 서버 전송 이벤트입니다. 각 이벤트는 `data: <JSON>` 형식이며, 여기서 JSON에는 `choices[0].delta.content`와 제공업체가 제공하는 경우 `id`, `object`, `created`, `model`, `original_model`, `usage`가 포함됩니다. 스트림은 `data: [DONE]`으로 끝납니다. |
| 스트리밍 없음 | 200, `application/json` | `{"choices": [{"message": {"role": "assistant", "content": "<text>"}}]}` |
| 본문이 JSON이 아니거나 `messages`가 누락되었거나 비어 있음 | 400, 일반 텍스트 | `Invalid request: messages required` |
| `model`이 `allowed_models`(`ai_provider_dxpr.settings` 소속, `ai_provider_dxpr` 모듈이 설치되고 목록이 설정된 경우에만 확인)에 없음. | 403, `application/json` | `{"error": {"code": "model_not_allowed", "message": "The selected model is not allowed. Please refresh the page to update your model options."}}` |
| 제공업체 예외 | 500, `application/json` | `{"error": {"message": "The request could not be completed."}}` |

### AI 이미지 생성

|  |  |
|---|---|
| 경로 | `/dxpr_builder/ajax/ai/image` |
| 라우트 | `dxpr_builder.ai_image` |
| 메서드 | POST |
| 요구 사항 | `edit with dxpr builder`, billable user, CSRF token |
| 컨트롤러 | `AiImageController::generate()` |

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `prompt` | JSON 본문 | 필수 | 텍스트 프롬프트. |
| `model` | JSON 본문 | 선택 | 기본값: `kavya-image`. |
| `size` | JSON 본문 | 선택 | 비어 있지 않으면 제공업체 구성에 전달됩니다. |
| `quality` | JSON 본문 | 선택 | 비어 있지 않으면 제공업체 구성에 전달됩니다. |
| `background` | JSON 본문 | 선택 | 비어 있지 않으면 제공업체 구성에 전달됩니다. |

응답:

| 사례 | 상태 | 본문 |
|---|---|---|
| 성공 | 200 | `{"data": [{"b64_json": "<base64 image>"}]}` (생성된 첫 번째 이미지만 반환됩니다) |
| 본문이 JSON이 아니거나 `prompt`이 누락됨 | 400 | `{"error": {"message": "Invalid request: prompt required"}}` |
| 제공업체가 이미지를 반환하지 않음 | 500 | `{"error": {"message": "No image was generated"}}` |
| 제공업체 예외 | 500 | `{"error": {"message": "Image generation failed. Please try again."}}` |

### AI 이미지 편집

|  |  |
|---|---|
| 경로 | `/dxpr_builder/ajax/ai/image/edit` |
| 라우트 | `dxpr_builder.ai_image_edit` |
| 메서드 | POST |
| 요구 사항 | `edit with dxpr builder`, billable user, CSRF token |
| 컨트롤러 | `AiImageController::edit()` |

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `prompt` | JSON 본문 | 필수 | 편집 지침. |
| `image` | JSON 본문 | 필수 | Base64로 인코딩된 원본 이미지(엄격한 디코딩). |
| `mimeType` | JSON 본문 | 선택 | 기본값: `image/png`. 서브타입이 제공업체에 전달되는 파일 확장자가 됩니다. |
| `model` | JSON 본문 | 선택 | 기본값: `kavya-image`. |
| `size`, `quality`, `background` | JSON 본문 | 선택 | 비어 있지 않으면 제공업체 구성에 전달됩니다. |

응답:

| 사례 | 상태 | 본문 |
|---|---|---|
| 성공 | 200 | `{"data": [{"b64_json": "<base64 image>"}]}` |
| 본문이 JSON이 아니거나 `prompt` 또는 `image`가 누락됨 | 400 | `{"error": {"message": "Invalid request: prompt and image required"}}` |
| `image`가 유효한 base64가 아님 | 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."}}` |

### 파일 업로드

|  |  |
|---|---|
| 경로 | `/dxpr_builder/ajax/file_upload` |
| 라우트 | `dxpr_builder.ajax_file_upload_callback` |
| 메서드 | POST, DELETE (라우팅에 선언됨. 컨트롤러에는 단일 업로드 핸들러만 있고 별도의 삭제 분기는 없습니다) |
| 요구 사항 | Billable user, CSRF token |
| 컨트롤러 | `UploadFileController::fileUpload()` |

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `upload` | 다음 필드명으로 전송되는 멀티파트 양식 파일: `upload[]` | 필수 | 하나 이상의 업로드된 파일. |

컨트롤러는 각 파일을 클라이언트 MIME 타입의 첫 부분에 따라 다음 중 하나로 분류합니다: `<default scheme>://dxpr_builder_images`, `dxpr_builder_videos` 또는 `dxpr_builder_files`. 이미지는 다음 MIME 타입의 확장자가 필요합니다. `image/gif`, `jpg`, `jpeg`, `png`, `webp`, `avif` 또는 `svg`. 동영상에는 다음 중 하나가 필요합니다. `video/webm`, `ogv`, `ogg`, `mp4` 또는 `quicktime` (예: `.mov`). 크기 제한은 PHP의 업로드 최대값입니다. 사용자가 볼 수 있는 기존 관리 파일과 이름과 SHA-256 콘텐츠가 동일한 파일은 다시 저장하지 않고 재사용합니다. 다음 모듈이 `media` 설치되고 다음 이름의 미디어 타입이 `image`, `media_image`, `video` 또는 `media_video` 있는 경우 파일에 대해 게시된 미디어 엔티티를 생성(또는 재사용)합니다. 파일 사용량은 다음에 기록됩니다: `dxpr_builder` 모듈.

응답:

| 사례 | 상태 | 본문 |
|---|---|---|
| 성공 | 201 | JSON 배열(파일당 하나의 객체): `url` (절대 파일 URL), `uuid` 및 `id` (미디어 엔티티가 있으면 해당 엔티티, 없으면 파일), `fid` (파일 ID), `entity_type` (`media` 또는 `file`). |
| `upload` 파일 없음 | 400 | `{"message": "No files were uploaded."}` |
| 잘못된 업로드, 쓸 수 없는 대상 또는 저장 실패 | 500 | `{"message": "<reason>"}` |
| 유효성 검사 실패(확장자 또는 크기) | 422 | `{"message": "<violation messages>"}` |
| 다른 요청이 파일 이름을 잠금 | 503 | `{"message": "File \"<name>\" is already locked for writing."}` |

### 미디어 라이브러리 대화상자

|  |  |
|---|---|
| 경로 | `/dxpr_builder/media-library` |
| 라우트 | `dxpr_builder.media_library` |
| 메서드 | 선언되지 않음(모든 메서드). 매개변수는 쿼리 문자열에서 읽습니다. |
| 요구 사항 | `view media`. 관리 라우트 |
| 컨트롤러 | `AjaxController::openImageMediaLibrary()` |

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `media_type` | 쿼리 문자열 | 선택 | `image` (기본값) 또는 `video`. |
| `remaining_slots` | 쿼리 문자열 | 선택 | 오프너가 허용하는 항목 수. 기본값은 1입니다. |
| `uuid` | 쿼리 문자열 | 선택 | 오프너 전달 값: `opener_parameters.uuid`. |

제공되는 미디어 타입은 `media_browser` 설정에 따라 다릅니다. `media_library`는 `image` 또는 `video` 미디어 타입을 직접 사용합니다. `media_library_acquia_dam`은 해당 미디어 타입이 있을 때 `acquia_dam_image_asset` 또는 `acquia_dam_video_asset`을 사용합니다.

응답:

| 사례 | 결과 |
|---|---|
| 성공 | 렌더 배열입니다. 빌드: `MediaLibraryUiBuilder::buildUi()`, 오프너: `media_library.opener.dxpr_builder`. Drupal은 이를 iframe용 HTML 페이지로 렌더링합니다. |
| `media_library` 모듈이 설치되지 않음 | 403, 일반 텍스트 `Media Library is not enabled. Please enable it to access this feature.` |
| 지원되지 않는 `media_type` | 400, 일반 텍스트 `Unsupported media type "<value>".` |
| `media_browser` 설정에 사용 가능한 미디어 타입이 없음 | 400, 일반 텍스트 `The "<setting>" settings is not supported.` |

### 도움말 링크 검사기

|  |  |
|---|---|
| 경로 | `/dxpr_builder/ajax/help_link_validator` |
| 라우트 | `dxpr_builder.ajax_help_link_validator` |
| 메서드 | 선언되지 않음(모든 메서드). 개발 스크립트 `dxpr_builder_dev.js` 양식으로 인코딩된 본문과 함께 POST를 전송합니다. |
| 요구 사항 | Billable user |
| 컨트롤러 | `AjaxController::validateHelpLink()` |

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `help_link` | POST 본문 | 의미 있는 답변에 필수 | 다음 호스트의 다음 URL만 확인됩니다. 프로토콜: `http`, `https`, 호스트: `dxpr.com`, 경로 시작: `/documentation/`. |

응답: JSON 배열입니다. `[true]`: 링크에 대한 HEAD 요청(리디렉션을 따르지 않음)이 200을 반환하는 경우. `[false]`: HTTP 클라이언트가 예외를 발생시키는 경우. `[]`: 매개변수 누락, 일치하지 않는 URL, 200이 아닌 상태를 포함한 그 외 모든 경우.

### 엔티티 링크 제안

|  |  |
|---|---|
| 경로 | `/dxpr_builder/entity-link-suggestions` |
| 라우트 | `dxpr_builder.entity_link_suggestions` |
| 메서드 | GET |
| 요구 사항 | `edit with dxpr builder`, CSRF token. `no_cache` 라우트 옵션 |
| 컨트롤러 | `EntityLinkSuggestionsController::suggestions()` |

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `q` | 쿼리 문자열 | 결과에 필수 | 검색 텍스트(소문자). 다음 같은 값은 `/node/123` 해당 엔티티를 직접 로드합니다. |
| `langcode` | 쿼리 문자열 | 선택 | 호스트 엔티티의 언어. 기본값은 현재 언어입니다. 이 언어에서 사용 가능한 엔티티만 반환됩니다. |

번들 정보에서 `ckeditor5_link_suggestions`이 활성화된 번들이 대상입니다. 구성된 번들이 없으면 모든 노드 번들을 검색합니다. 엔티티 타입당 최대 100개의 엔티티가 코어의 엔티티 참조 선택 플러그인을 통한 `CONTAINS` 검색으로 일치됩니다.

응답: `{"suggestions": [...]}` 프라이빗 캐시 가능성과 최대 300초의 수명을 가집니다. 각 제안에는 `description`, `entity_type_id`, `entity_uuid`, `group`, `label`, `path`가 있습니다. `q`가 아무것도 일치하지 않으면 배열에는 `description`, `label`(소문자로 변환된 입력), `path`(유효한 URL인 경우 입력, 그렇지 않으면 빈 문자열)를 포함하는 단일 수동 링크 제안이 있습니다. `q`가 비어 있으면 `suggestions`가 빈 배열입니다.

### 사용자 에디터 설정

|  |  |
|---|---|
| 경로 | `/dxpr_builder/user-settings` |
| 라우트 | `dxpr_builder.user_settings` |
| 메서드 | POST |
| 요구 사항 | `edit with dxpr builder`, CSRF token. `no_cache` 라우트 옵션 |
| 컨트롤러 | `UserSettingsController::save()` |

사용자가 자신의 에디터 설정을 변경할 때 에디터에서 이 요청을 전송합니다(예: **Editor settings** 아래). 값은 `user.data`의 사용자 계정과 함께 저장됩니다(모듈 `dxpr_builder`).

| 매개변수 | 출처 | 필수 여부 | 참고 |
|---|---|---|---|
| `controls_layout` | JSON 본문 | 필수(유일한 설정) | `element`, `breadcrumb` 또는 `default`. `default` 사용자의 선택을 제거하므로 프로필 또는 사이트 설정이 적용됩니다. |

응답:

| 사례 | 상태 | 본문 |
|---|---|---|
| 저장됨 | 200 | `{"settings": {"controls_layout": "<value>"}}`: 저장 후 모든 설정입니다. 다음은 사용자가 저장한 선택이 없는 경우: `default`. |
| 본문이 비어 있지 않은 JSON 객체가 아니거나 이름 또는 값이 잘못됨 | 400 | `{"error": "Invalid setting or value."}`. 아무것도 저장되지 않습니다. |

## 주요 AJAX 핸들러 작업

모든 작업은 토큰 쿼리 매개변수와 함께 `/dxpr_builder/ajax`로 이동합니다(토큰은 `/dxpr_builder/csrf`에서 얻음). 작업 이름은 POST 본문 필드 `action`으로 전송됩니다. 다른 모든 매개변수는 별도 명시가 없으면 POST 본문 필드입니다. "과금 여부 재확인" 열은 내부 스위치에서 `isBillableUser()`를 다시 호출하는 작업을 표시합니다. 해당 확인이 실패하면 행에 별도 명시가 없는 한 위에 설명된 빈 `AjaxResponse`를 반환합니다.

### 세션 및 접근

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_login` | 없음 | 아니요 | JSON 불리언: 현재 사용자가 billable user인지 여부. |
| `dxpr_builder_csrf` | 없음 | 예 | JSON 문자열: `token` 쿼리 매개변수가 포함된 핸들러 URL입니다(`/dxpr_builder/csrf`와 동일하나 `enterprise` 옵션 제외). |

### 컨테이너(DXPR Builder 포매터로 렌더링된 필드)

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_get_container_types` | 없음 | 예 | JSON 객체입니다. 키: `entity_type\|bundle`, 값: `entity_type - bundle`. 기본 보기 디스플레이가 하나 이상의 필드에서 `dxpr_builder_text` 포매터를 사용하는 각 번들마다 하나의 항목이 있습니다. |
| `dxpr_get_container_names` | `container_type` (필수, `entity_type\|bundle`) | 예(빈 응답 대신 빈 JSON 문자열을 반환합니다) | JSON 객체입니다. 키: `entity_id\|field_name`(또는 `entity_id\|field_name\|langcode` 번역 가능한 엔티티의 경우), 값: `entity label\|field label`입니다. `container_type`이 누락되었거나 과금 확인이 실패하면 응답은 빈 JSON 문자열입니다. |
| `dxpr_save_container` | `type` (필수, `entity_type\|bundle`); `name` (필수, `entity_id\|field_name` 또는 `entity_id\|revision_id\|field_name`); `htmlContent` (필수, 인코딩된 마크업); `lang` (선택, 기본값은 사이트 기본 언어) | 예 | 성공 시 JSON 빈 문자열. `htmlContent`가 문자열이 아니거나 언어가 번역 불가능한 엔티티에 적용되지 않으면 JSON 메시지와 함께 HTTP 400. 요청된 번역이 없으면 404. 엔티티를 로드할 수 없으면 500. |

`dxpr_save_container`은 다음을 수행합니다:

1. 디코딩: `htmlContent`. 모든 바이트를 7과 XOR한 뒤 URL 디코딩합니다.
2. 결과를 지정된 필드의 첫 번째 델타에 씁니다.
3. 엔티티 타입에 리비전이 있으면 `Saved with DXPR builder` 로그 메시지와 함께 새 기본 리비전을 생성합니다.
4. 엔티티의 콘텐츠 잠금을 모두 제거합니다.
5. 저장된 인라인 블록을 참조하는 Layout Builder 섹션에서 `block_revision_id`를 업데이트합니다.
6. 증가: `dxpr_builder.saves_count` 상태 값.

사용자에게 엔티티에 대한 다음 접근 권한이 있을 때만 저장됩니다: `update`. 없으면 작업은 여전히 빈 문자열 성공 응답을 반환합니다.

### CMS 요소(블록 및 뷰)

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_builder_get_cms_element_names` | 없음 | 예 | JSON 객체입니다. 출처: `DxprBuilderService::getCmsElementNames()`, 키: `list`, `disallowed`, `blockCategories`. |
| `dxpr_get_cms_element_settings` | `name` (필수): `view-<view_id>-<display_id>` 또는 `block-<plugin_id>`. `ajax_page_state[libraries]` (선택, 이미 로드된 쉼표로 구분된 라이브러리) | 예 | JSON 객체입니다. 포함: `css`, `js`, `settings`, `data`. 뷰의 경우 `data`는 렌더링된 노출 필터 위젯입니다. 블록의 경우 `data`는 `<form>` 태그로 감싼 블록의 구성 양식이며, 제거된 요소: `provider`, `admin_label`, `label`, `label_display`, `context_mapping`이고 모든 details 요소는 열립니다. |
| `dxpr_builder_load_cms_element` | `name` (필수, `parseStringForCmsElementInfo()`에서 파싱). `settings` (필수). `data` (필수, 배열). `ajax_page_state[libraries]` (선택) | 아니요 | JSON 객체입니다. 포함: `css`, `js`, `settings`, `data`, 여기서 `data`는 렌더링된 블록 또는 뷰 디스플레이입니다. |

두 작업에서 `settings`를 반환할 때 `css`와 `js`는 페이지에 아직 없는 렌더링된 애셋 태그이며, `settings`는 디코딩된 `drupalSettings` 객체이거나 없는 경우 빈 문자열입니다.

### 페이지 템플릿

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_get_page_templates` | 없음 | 예 | 활성화된 페이지 템플릿의 JSON 배열입니다. 각 항목에는 `title`, `uuid`, `module`(항상 `null`: 엔티티에 저장하지 않음), `category`, `date`, `weight`(정수), `image`(`data:` URL 또는 모듈의 `not-found.png` URL)가 있습니다. |
| `dxpr_load_page_template` | `uuid` (필수) | 예 | 베이스 토큰이 교체된 템플릿 마크업을 포함한 HTML 응답. 일치하는 활성화된 템플릿이 없으면 비어 있습니다. |

### 사용자 템플릿

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_get_templates` | 없음 | 예 | 현재 사용자가 소유하거나 전역으로 표시된 템플릿의 JSON 배열입니다. 작성자 계정이 더 이상 존재하지 않는 템플릿은 제외됩니다. 각 항목에는 `id`, `uuid`, `name`, `global`, `current_user_is_author`, `author_id`, `author_name`, `type`, 저장된 경우 `image`(`data:` URL)가 있습니다. |
| `dxpr_load_template` | `uuid` (필수) | 예 | 베이스 토큰이 교체된 템플릿 마크업을 포함한 HTML 응답. 일치하는 활성화된 템플릿이 없으면 비어 있습니다. |
| `dxpr_save_template` | `name` (필수). `template` (필수, 마크업). `type` (선택, 기본값: `custom` ). `global` (선택, 불리언으로 캐스팅). `image` (선택: POST 본문의 base64 문자열 또는 `data:image` URL, 또는 다음 이름의 멀티파트 파일 필드: `image`) | 예 | JSON 객체입니다. 포함: `message`, `code`. 성공 시 `code` 200, 동일한 머신 이름의 템플릿이 있으면 `code` 409(HTTP 상태는 200), 이미지가 유효한 이미지 데이터가 아니면 HTTP 400과 함께 `code` 400입니다. |
| `dxpr_delete_template` | `name` (필수) | 예 | JSON 빈 문자열. |

머신 이름은 `name`에서 파생됩니다. 소문자로 변환하고 `a-z0-9_` 외부의 모든 연속 문자를 밑줄로 교체합니다. `type`은 저장된 템플릿에 타입이 없을 때 마크업의 `data-azb` 속성 값을 사용합니다.

### 이미지

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_builder_get_image_urls` | `entityIDs` (필수, 배열). `imageStyle` (필수. `original` 스타일 없는 파일의 경우). `entityType` (필수. `media` 미디어 항목을 해석하고, 다른 모든 값은 ID의 엔티티 타입으로 사용합니다) | 예 | 텍스트 본문: 쉼표로 구분된 이미지 URL. 파일은 `fid` 쿼리 매개변수가 포함된 루트 상대 URL을 제공합니다. `image` 또는 `video` 타입의 미디어 항목은 소스 파일로 해석됩니다. `acquia_dam_image_asset` 항목은 `mid`, `acquiaDamAsset`, `imageStyle`이 추가된 DAM URL을 제공합니다. 다른 미디어 항목은 건너뜁니다. `entityIDs`가 비어 있거나 어떤 미디어 항목도 해석할 수 없으면 본문 없이 HTTP 204를 반환합니다. |
| `dxpr_builder_get_image_style_url` | `imageStyle` (필수). `entityId` (필수). `entityTypeId` (필수, `file` 또는 `media`) | 예 | 텍스트 본문. 파일의 경우 이미지 스타일을 통한 루트 상대 URL입니다(SVG 파일과 `original`은 스타일을 건너뜁니다). `fid` 쿼리 매개변수와 함께 제공됩니다. `acquia_dam_image_asset` 미디어 항목의 경우 DAM URL입니다. 다른 엔티티나 찾을 수 없는 엔티티에는 본문 없이 HTTP 204를 반환합니다. |
| `dxpr_builder_get_image_metadata` | `entityId` (필수). `entityType` (필수, `file` 또는 `media`) | 예(빈 응답 대신 403 JSON을 반환합니다) | `{"data": {"alt": "...", "title": "..."}}` 미디어 항목의 이미지 소스 필드에서 가져옵니다(Acquia DAM 애셋은 DAM 대체 텍스트와 빈 제목을 제공합니다). 파일의 경우 `field_media_image`가 해당 파일을 참조하는 첫 번째 미디어 항목에서 값을 가져옵니다. `data`는 엔티티가 파일도 미디어 항목도 아니거나 어떤 미디어도 파일을 참조하지 않으면 빈 배열입니다. 오류: 400 `{"error": "Missing required parameters"}`, 404 `{"error": "Entity not found"}`, 500 `{"error": "Failed to load entity"}`, 403 `{"error": "Access denied"}`. |

### 콘텐츠 잠금

| 작업 | 매개변수 | 과금 여부 재확인 | 반환값 |
|---|---|---|---|
| `dxpr_content_lock_status` | `entity_id`, `revision_id`, `entity_type`, `langcode` (모두 필수) | 아니요 | JSON 객체입니다. 포함: `status`(불리언), `label`(엔티티 라벨). 잠긴 경우 추가로: `entity_lock_author_id`, `entity_lock_author_name`. |
| `dxpr_toggle_content_lock` | `entity_id`, `revision_id`, `entity_type`, `langcode`, `toggle_action` (모두 필수. `lock` 잠금을 생성하고 다른 모든 값은 잠금을 제거합니다) | 아니요 | JSON 객체입니다. 포함: `label`, `status`(`true` 잠금 후, `false` 잠금 해제 후). 다음 경우 빈 JSON 배열: `[]`(엔티티를 로드할 수 없거나 사용자에게 `update` 접근 권한이 없을 때). |

## 관리 페이지

이러한 라우트는 모두 모든 메서드를 허용합니다(`methods` 키 없음). `{...}`이 포함된 경로는 구성 엔티티 ID를 사용하고, `{migration_id}`의 경우 마이그레이션 ID를 사용합니다.

| 경로 | 라우트 | 권한 | 목적 |
|---|---|---|---|
| `/admin/dxpr_studio` | `dxpr_builder.admin.studio` | `administer dxpr builder configuration` | DXPR Studio 개요. 하위 페이지를 나열하는 코어의 관리 메뉴 블록 페이지입니다. |
| `/admin/dxpr_studio/dxpr_builder` | `dxpr_builder.admin.studio.builder` | `administer dxpr builder configuration` | DXPR Builder 개요. 코어의 관리 메뉴 블록 페이지입니다. |
| `/admin/dxpr_studio/dxpr_builder/settings` | `dxpr_builder.settings` | `administer dxpr builder configuration` | `DxprBuilderSettingsForm`: 모듈 설정 양식입니다. |
| `/admin/dxpr_studio/dxpr_builder/ai_settings` | `dxpr_builder.ai_settings` | `administer dxpr builder configuration` | `DxprBuilderAiSettingsForm`: AI 설정 양식입니다. |
| `/admin/dxpr_studio/dxpr_builder/user_templates` | `entity.dxpr_builder_user_template.collection` | `administer site configuration` | 구성 엔티티 목록: `dxpr_builder_user_template`. |
| `/admin/dxpr_studio/dxpr_builder/user_templates/add` | `entity.dxpr_builder_user_template.add_form` | `administer site configuration` | 사용자 템플릿을 추가합니다. |
| `/admin/dxpr_studio/dxpr_builder/user_templates/{dxpr_builder_user_template}` | `entity.dxpr_builder_user_template.edit_form` | `administer site configuration` | 사용자 템플릿을 편집합니다. |
| `/admin/dxpr_studio/dxpr_builder/user_templates/{dxpr_builder_user_template}/delete` | `entity.dxpr_builder_user_template.delete_form` | `administer site configuration` | 사용자 템플릿을 삭제합니다(확인 양식). |
| `/admin/dxpr_studio/dxpr_builder/page_template` | `entity.dxpr_builder_page_template.collection` | `administer site configuration` | 구성 엔티티 목록: `dxpr_builder_page_template`. |
| `/admin/dxpr_studio/dxpr_builder/page_template/add` | `entity.dxpr_builder_page_template.add_form` | `administer site configuration` | 페이지 템플릿을 추가합니다. |
| `/admin/dxpr_studio/dxpr_builder/page_template/create` | `dxpr_builder.create_page_template` | `administer dxpr builder configuration` | `PageController::createPageTemplate()`: `uuid` 쿼리 매개변수로 식별된 활성화된 사용자 템플릿을 동일한 ID와 `DXPR` 카테고리로 새 페이지 템플릿에 복사합니다. 상태 또는 오류 메시지를 설정하고 사용자 템플릿 목록으로 리디렉션합니다. |
| `/admin/dxpr_studio/dxpr_builder/page_template/{dxpr_builder_page_template}` | `entity.dxpr_builder_page_template.edit_form` | `administer site configuration` | 페이지 템플릿을 편집합니다. |
| `/admin/dxpr_studio/dxpr_builder/page_template/{dxpr_builder_page_template}/delete` | `entity.dxpr_builder_page_template.delete_form` | `administer site configuration` | 페이지 템플릿을 삭제합니다(확인 양식). |
| `/admin/dxpr_studio/dxpr_builder/profile` | `entity.dxpr_builder_profile.collection` | `administer dxpr_builder_profile` | 구성 엔티티 목록: `dxpr_builder_profile`. |
| `/admin/dxpr_studio/dxpr_builder/profile/add` | `entity.dxpr_builder_profile.add_form` | `administer dxpr_builder_profile` | 프로필을 추가합니다. |
| `/admin/dxpr_studio/dxpr_builder/profile/{dxpr_builder_profile}` | `entity.dxpr_builder_profile.edit_form` | `administer dxpr_builder_profile` | 프로필을 편집합니다. |
| `/admin/dxpr_studio/dxpr_builder/profile/{dxpr_builder_profile}/delete` | `entity.dxpr_builder_profile.delete_form` | `administer dxpr_builder_profile` | 프로필을 삭제합니다(확인 양식). |
| `/admin/dxpr_studio/dxpr_builder/user_licenses` | `dxpr_builder.user_licenses` | `administer dxpr builder configuration` | `PageController::userLicensesPage()`: 라이선스 사용자의 캐시되지 않은 테이블입니다(열: User, Roles, Sites, Assigned, Operations). 그 위에는 라이선스 정보를 사용할 수 있는 경우 자체 라이선스 요약 카드(`dxpr-license-info`)가 렌더링됩니다. 해제된 라이선스가 30일을 기다리는 동안에는 "Next license available on" 알림이 표시됩니다. 이 라우트에서는 **License info** 블록이 아무것도 렌더링하지 않으므로 요약이 두 번 표시되지 않습니다. |
| `/admin/dxpr_studio/dxpr_builder/user_licenses/sites` | `dxpr_builder.user_licenses.sites` | `administer dxpr builder configuration` | `PageController::userLicensesSitesPage()`: 다음 요청 매개변수에 지정된 사용자에게 기록된 도메인의 항목 목록: `mail`. 라이선스 테이블에서 모달로 열립니다. |
| `/admin/dxpr_studio/dxpr_builder/content` | `dxpr_builder.licensed_content` | `administer dxpr builder configuration` | `PageController::licensedContentPage()`: DXPR Builder로 편집한 콘텐츠 항목의 페이지 매김 테이블입니다(페이지당 20개). 콘텐츠 항목 라이선스 요약과 함께 제공합니다. `needs_migration=1` 쿼리 매개변수는 콘텐츠 마이그레이션이 필요한 항목만 표시합니다. 라이선스 정보를 사용할 수 없으면 비어 있습니다. |
| `/admin/dxpr_studio/dxpr_builder/migration-status` | `dxpr_builder.migration_status` | `administer dxpr builder configuration` | `MigrationStatusController::statusPage()`: 보류 항목과 함께 등록된 콘텐츠 마이그레이션의 캐시되지 않은 테이블입니다. 보류 중인 각 마이그레이션에는 다음 링크가 있습니다: **Run now**. 보류 중인 항목이 있으면 다음 버튼이 표시됩니다: **Run all pending migrations**. |
| `/admin/dxpr_studio/dxpr_builder/migration-run/{migration_id}` | `dxpr_builder.migration_run_confirm` | `administer dxpr builder configuration` | `MigrationRunConfirmForm`: 하나의 마이그레이션을 확인한 뒤 배치로 실행하고 상태 페이지로 돌아갑니다. |
| `/admin/dxpr_studio/dxpr_builder/migration-run-all` | `dxpr_builder.migration_run_all_confirm` | `administer dxpr builder configuration` | `MigrationRunAllConfirmForm`: 등록된 모든 마이그레이션을 확인한 뒤 하나의 배치로 실행하고 상태 페이지로 돌아갑니다. |
| `/dxpr-builder/disavow-user` | `dxpr_builder.disavow_user_confirm` | `administer dxpr builder configuration` | `DisavowUserConfirmForm`: `uid` 쿼리 매개변수에 지정된 사용자를 DXPR Builder 편집에서 제외하는 것을 확인합니다. |
| `/dxpr-builder/delete-stale-user` | `dxpr_builder.delete_stale_user_confirm` | `administer dxpr builder configuration` | `DeleteStaleUserConfirmForm`: `email` 쿼리 매개변수에 지정된 이메일 주소의 라이선스 데이터 제거를 확인합니다. |

## 다음 단계

- [Configuration reference](/ko/hc/documentation/learn-dxpr-builder/reference/config-reference): 이러한 엔드포인트에서 사용하는 미디어 브라우저와 AI 동작을 제어하는 설정입니다.
- [PHP API](/ko/hc/documentation/learn-dxpr-builder/development/api): 컨트롤러가 호출하는 서비스입니다.
- [Hooks API](/ko/hc/documentation/learn-dxpr-builder/development/hooks-api): 다른 모듈이 빌더 동작을 변경할 수 있는 훅입니다.