# Create external web link

`POST /api/configuration/externalweblinks`

- **Products:** Operator (`FOH`)
- **Features:** Front of House Generic Access (`FOHGENERIC`)

HTML version: [Create external web link](https://support.gladstonesoftware.cloud/reference/configuration/create-external-web-link)

## Overview

Creates one external web link — a stored URL that the tenant's front-of-house and member-facing applications render as a link or tile. Each link hangs off a **link type**, which is the slot in the host application the link fills. Link types are reference data you do not create here; list them with [Get all external web link types](get-all-external-web-link-types.md) and send the `id` you want as `linkTypeId`.

The identifier is generated by the system — you cannot choose it. On success you get `201 Created` with a body of `{"externalWebLinkId": 1234}`. No `Location` header is set, so read the id from the body. Keep it: it is the `{id}` for [Update external web link](update-external-web-link.md) and [Delete external web links](delete-external-web-links.md).

There is no idempotency key and no duplicate detection on URL or description, so **retrying a request that already succeeded creates a second link with a new id**. If a retry is ambiguous, list the existing links before retrying rather than sending the call again.

The only uniqueness rule is per link type. Each link type carries an `allowMultiples` flag. When it is false, the type may hold exactly one link, and a second create against it fails with `400` and `External Web Link Type Id '{linkTypeId}' does not allow multiple entries.` — note that this is a `400`, not a `409`. When `allowMultiples` is true, any number of links may share the type.

Validation runs before anything is saved, so a rejected request leaves no partial link.

## Endpoint

`POST {base_url}/api/configuration/externalweblinks`

`{base_url}` is the environment URL issued to your integration. See [Authenticating with Gladstone APIs](../../guides/authenticating-with-gladstone-apis.md).

## Request body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `linkTypeId` | integer (int32) | Yes | The slot the link occupies in the host application, taken from the `id` of an entry returned by [Get all external web link types](get-all-external-web-link-types.md). Link types are existing reference data; this endpoint will not create one for you. A value that matches no type — including the `0` you get by omitting the field — is rejected with `400` and `External Web Link Type Id '{value}' not found.` If the type has `allowMultiples` set to false and a link already uses it, the request is rejected instead with the "does not allow multiple entries" message. |
| `description` | string | Yes | The human-readable label the host application shows for the link, rather than an internal note — this is the text a member or staff user sees. Maximum 255 characters. Must be present and non-empty; omitting it, or sending `null` or `""`, is rejected with `400` and `Invalid request: No description provided.` |
| `url` | string | Yes | The destination the link opens. Must be an absolute URL with an `http` or `https` scheme — a relative path, a bare hostname such as `www.example.com`, or any other scheme (`ftp:`, `mailto:`) is rejected with `400` and `URL '{value}' is not a valid URL.` Maximum 255 characters. Must be present and non-empty, or you get `400` and `Invalid request: No URL provided.` |
| `image` | string | No | Absolute URL of an icon or thumbnail the host application displays alongside the link. Optional — omit it, or send `null` or `""`, and the link is created with no image. When supplied it must be `http` or `https` and the path must end in `.svg`, `.jpeg`, `.jpg`, `.gif` or `.png` (case-insensitive); anything else, including a URL with no file extension, is rejected with `400` and `Image URL '{value}' is not a valid URL.` Maximum 255 characters. |
| `targetType` | string | Yes | How the host application should open the destination. Must be present and non-empty, or you get `400` and `Invalid request: No target type provided.` The value is **not** validated beyond that, and whatever you send is saved, up to 40 characters — so a typo is accepted here and only surfaces as a broken link in the consuming application. Gladstone's own staff UI writes `Internal` or `External`; match those exactly unless the application you are integrating with expects something else. |
| `domainBrowsing` | boolean | No | Whether the host application confines the user to the single page at `url` or lets them browse the wider domain from it. Not validated; saved as given. `true` corresponds to the full-domain option and `false` to single-page-only in Gladstone's staff UI. Omitting it or sending `null` saves `false`. |
| `status` | string | No | Whether the link is live. Accepts `Active` or `InActive`, matched case-insensitively but saved exactly as you sent it, so send the value in the casing your consuming application compares against. **Omitting the field, or sending `null` or `""`, saves `InActive`** — a created link is therefore hidden by default and needs a follow-up [update](update-external-web-link.md), or an explicit `"status": "Active"` here, to appear. Any other value is rejected with `400` and `Invalid request: Status must be either 'Active' or 'InActive'.` |

## Sample request

```bash title="cURL"
curl -X POST '{base_url}/api/configuration/externalweblinks' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true' \
  -H 'Content-Type: application/json' \
  -d '{
  "linkTypeId": 12345,
  "description": "string",
  "url": "string",
  "image": "string",
  "targetType": "string",
  "domainBrowsing": true,
  "status": "string"
}'
```

## Errors

Error bodies for the `400`s below are a bare JSON string containing the message quoted in the "When" column — not a problem-details object. The exception is a malformed body, which returns a validation problem document (`application/problem+json`, RFC 7807) with an `errors` map keyed by field name. Check the shape before parsing.

| Status | Meaning | When |
|--------|---------|------|
| `400` | Malformed request body | The JSON is unparseable, the body is missing entirely, or a value is of the wrong type — for example a non-numeric `linkTypeId` or a string `domainBrowsing`. Rejected before any other check runs; the body is a validation problem document. |
| `400` | No description provided | `description` is missing, `null` or empty. Message: `Invalid request: No description provided.` |
| `400` | No target type provided | `targetType` is missing, `null` or empty. Message: `Invalid request: No target type provided.` |
| `400` | No URL provided | `url` is missing, `null` or empty. Message: `Invalid request: No URL provided.` |
| `400` | URL is not a valid absolute http/https URL | `url` is not parseable as an absolute URI, or its scheme is neither `http` nor `https`. Message: `URL '{url}' is not a valid URL.` |
| `400` | Image URL is not a valid image URL | `image` is supplied but does not match the expected `http`/`https` form ending in `.svg`, `.jpeg`, `.jpg`, `.gif` or `.png`. Message: `Image URL '{image}' is not a valid URL.` |
| `400` | Link type does not exist | No external web link type has the supplied `linkTypeId` — including `0`, the value you get by omitting the field. Message: `External Web Link Type Id '{linkTypeId}' not found.` |
| `400` | Invalid status | `status` is supplied but is neither `Active` nor `InActive` (compared case-insensitively). Message: `Invalid request: Status must be either 'Active' or 'InActive'.` |
| `400` | Link type already in use and does not allow multiples | The link type exists with `allowMultiples` set to false and already has a link against it. Message: `External Web Link Type Id '{linkTypeId}' does not allow multiple entries.` This is the duplicate case, and it returns `400` rather than `409`. |
| `403` | Forbidden | The token does not carry the scope this endpoint requires. Anonymous and member tokens are both rejected here; use an integration token. |
| `500` | Internal server error | An unexpected server-side failure after validation has passed, for example while saving the link. The body is empty; nothing is created. Safe to retry, but confirm the link was not created before you do, since retries are not deduplicated. |
