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

# Insert Surface

> API for registering a Surface via API.

This document provides a guide and overview for the InsertSurface RPC, which allows you to register a Surface directly via API. A Surface must exist before it can be referenced by name in `InsertTreatmentType` or `UpdateTreatmentType`, so this endpoint removes the manual console step from an otherwise API-driven treatment type integration.

## API Definition

```url theme={null}
POST https://apis.auxia.io/v1/InsertSurface
```

<Note>
  `InsertSurface` requires a **Treatment Management** API key, passed in the `x-api-key` header. A key without Treatment Management permissions is rejected with `403 PERMISSION_DENIED`. The key is validated against the `projectId` in the request: a key issued for one project cannot create a Surface on another.
</Note>

## Entities

### SurfacePb

```
message SurfacePb {
  // The Surface name. Surfaces are referenced by name everywhere in the API,
  // so there is no separate Auxia-side identifier to store.
  string surface_name = 1;
}
```

## InsertSurface

### API to register a Surface

```
message InsertSurfaceRequest {
  // Required.
  // Numeric project id.
  string project_id = 1;

  // Required.
  // Must match ^[A-Za-z][A-Za-z0-9_]*$, with a maximum length of 200 characters.
  // Cannot be "All" in any casing.
  string surface_name = 2;

  // Required.
  // Identifies who made the change, for audit purposes. Typically an email address.
  string last_modified_by = 3;
}

message InsertSurfaceResponse {
  // The registered Surface (or the pre-existing one, if it already existed).
  SurfacePb surface = 1;
}
```

### Surface name rules

| Rule            | Detail                                                 |
| --------------- | ------------------------------------------------------ |
| Pattern         | `^[A-Za-z][A-Za-z0-9_]*$`                              |
| First character | Must be a letter. A leading digit is rejected.         |
| Allowed         | Upper case, lower case, digits (not first), underscore |
| Rejected        | Hyphens, spaces, and any other punctuation             |
| Max length      | 200 characters                                         |
| Reserved        | `All`, in any casing                                   |

<Tip>
  InsertSurface is idempotent on `(project_id, surface_name)`. Calling it again with the same project and name returns the existing Surface without creating a duplicate or returning an error. Retrying after a network timeout is therefore always safe, and there is no need to track which Surfaces have already been created - call it unconditionally before referencing a Surface by name.
</Tip>

:::caution
Surfaces cannot be deleted. Creating one also provisions the per-Surface event schemas and data fields behind it. Validate the name on your side before calling, since a typo results in a permanent Surface.
:::

### Sample cURL Request

```
curl --location --request POST 'https://apis.auxia.io/v1/InsertSurface' \
--header 'Content-Type: application/json' \
--header 'x-api-key: API_KEY' \
--data-raw '{
  "projectId": "PROJECT_ID",
  "surfaceName": "IN_APP_CONTENT",
  "lastModifiedBy": "USER_EMAIL"
}'
```

### Sample Response

```
{
  "surface": {
    "surfaceName": "IN_APP_CONTENT"
  }
}
```

### Errors

| HTTP | Condition                                                                                  |
| ---- | ------------------------------------------------------------------------------------------ |
| 400  | `surfaceName` does not match the required pattern, for example a leading digit or a hyphen |
| 400  | `surfaceName` is the reserved value `All`, in any casing                                   |
| 400  | `surfaceName` or `lastModifiedBy` is empty, or `projectId` is not numeric                  |
| 403  | The API key does not have Treatment Management permissions                                 |
| 403  | The API key is valid but belongs to a different project                                    |
| 403  | No API key was supplied                                                                    |

## Registering a Surface and a Treatment Type together

`InsertTreatmentType` and `UpdateTreatmentType` validate that every Surface named in `surfaces` already exists for the project, and reject the request with `400` otherwise:

```
{"code":400,"message":"The following surfaces do not exist for project_id PROJECT_ID: IN_APP_CONTENT"}
```

Call `InsertSurface` first for each Surface name, then reference those names in the treatment type request:

1. `POST /v1/InsertSurface` for each Surface the treatment type will use
2. `POST /v1/InsertTreatmentType` with `surfaces: [{ "surfaceName": "IN_APP_CONTENT" }]`
3. `POST /v1/InsertTreatment` to add content to the treatment type

Because step 1 is idempotent, it is safe to run on every treatment type creation rather than only the first time a Surface is used.
