# Get external web link by ID or link type ID

`GET /api/configuration/externalweblinks/{id}`

- **Success:** `200 OK`
- **Products:** Operator (`FOH`), Consumer (`CONSUMER`) (any one of these products, not all)
- **Features:** Online Bookings (`ONLINEBOOK`), Online Joining (`ONLINEJOIN`), Front of House Generic Access (`FOHGENERIC`) (any one of these features, not all)

HTML version: [Get external web link by ID or link type ID](https://support.gladstonesoftware.cloud/reference/configuration/get-external-web-link-by-id-or-link-type-id)

## Overview

An external web link is an operator-configured outbound link — a destination URL, display text and an optional image — that the consumer-facing apps render as a navigation entry or tile. Every link belongs to a **link type**, a separate operator-configured record that says where in the app links of that type appear. The only link type a new tenant starts with is `Home`; operators add their own.

**This single route performs two different lookups, and the `idType` query parameter alone decides which.** The `{id}` route segment is just a number — nothing about it says what kind of identifier it is.

- `?idType=id` — treat `{id}` as the identifier of one web link.
- `?idType=linkTypeId` — treat `{id}` as the identifier of a **link type**, and return every link of that type.

The comparison against those two values is an exact, case-sensitive string match. `ID`, `Id`, `linktypeid` and `LinkTypeId` are all rejected with `400`. Omitting `idType`, or sending it empty, is also rejected with `400` — so despite being a query parameter it is mandatory in practice. There is no default and no fallback: the endpoint never guesses which lookup you meant, and there is no way to supply both kinds of identifier in one call.

Both branches return `200` with a JSON **array**, so the single-link lookup gives you an array of one rather than a bare object. Handle the response as a list in both cases.

The two branches differ in what "not found" means, and the difference matters:

- `idType=id` with an id no link has returns `404`. It never returns an empty array.
- `idType=linkTypeId` with an id no **link type** has returns `404`.
- `idType=linkTypeId` for a link type that exists but currently has no links returns `200` with `[]`.

So an empty array means "that link type exists and is empty", never "not found". A link type that permits multiple links can return many records in one call; the response is not paginated and has no defined ordering.

Both identifiers are integers allocated within a single tenant. **They are not stable across tenants or environments** — id `3` on one operator's system is an unrelated record on another's. Never hardcode either. Take a web link id from [Get all external web links](get-all-external-web-links.md), and a link type id from [Get all external web link types](get-all-external-web-link-types.md), which is also where you resolve a link type id to its name.

**Retired links are still returned.** Each record carries a `status` of `Active` or `InActive`, and this endpoint filters only on the identifier — it does not filter on `status`. Both lookups return deactivated links alongside live ones, so if you are rendering these to end users you must exclude `status` of `InActive` yourself.

## Endpoint

`GET {base_url}/api/configuration/externalweblinks/{id}`

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

## Path parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | integer (int32) | Yes | The identifier to look up. What it identifies depends entirely on `idType`: with `idType=id` it is a web link's own identifier, and with `idType=linkTypeId` it is a link type's identifier. Both are tenant-scoped integers with no meaning outside one operator's system — take them from [Get all external web links](get-all-external-web-links.md) or [Get all external web link types](get-all-external-web-link-types.md) rather than hardcoding them. It must be a 32-bit integer; a non-numeric or out-of-range value is rejected with `400` before the lookup runs. |

## Query parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `idType` | string | Yes | Selects which lookup to perform. Only two literal values are accepted, matched case-sensitively: `id` looks up the single web link whose identifier is `{id}`, and `linkTypeId` returns every web link belonging to the link type whose identifier is `{id}`. Although it is a query parameter, it is mandatory: the endpoint returns `400 Id Type query parameter is required.` when it is missing or empty, and with `400 Provided idType query parameter is not valid.` for any other value. There is no default. |

## Sample request

```bash title="cURL"
curl -X GET '{base_url}/api/configuration/externalweblinks/7?idType=linkTypeId' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true'
```

## Response fields

| Field | Type | Description |
|-------|------|-------------|
| `[].id` | integer (int32) | The web link's own identifier, allocated by the platform when the link was created. Pass it back as `{id}` with `idType=id` to re-read this single link, and to the update and delete endpoints. Tenant-scoped — not portable between operators or environments. |
| `[].linkTypeId` | integer (int32) | The link type this link belongs to, which is what determines where the app displays it. Pass this value as `{id}` with `idType=linkTypeId` to retrieve every sibling link of the same type. Resolve it to a human-readable name with [Get all external web link types](get-all-external-web-link-types.md). Always populated. |
| `[].description` | string | The operator-supplied display text for the link, used as the caption or label rather than as an internal note. Maximum 255 characters, and writes reject an empty value, so this is never null or empty on a record created through the API. |
| `[].url` | string | The destination the link navigates to. At most 255 characters, and always an absolute `http` or `https` URL — writes are validated against that and reject relative paths and other schemes. Never null on a record created through the API. |
| `[].image` | string | The image the app renders alongside the link, if the operator configured one. The operator can configure it in two forms, which are normalised on the way out: a value already beginning with `http` (matched case-insensitively) is returned unchanged, while anything else is treated as a bare filename and expanded to `{publicCdnUrl}/public/{tenantId}/images/{filename}`. `null` when no image is configured — but also `null` when a filename **is** configured and the deployment has no public CDN URL set, so a null value here does not on its own prove that no image was chosen. Writes accept only URLs ending in `.svg`, `.jpeg`, `.jpg`, `.gif` or `.png`. |
| `[].targetType` | string | Operator-supplied string of at most 40 characters, rejected when empty on write, so it is always populated on a record created through the API. |
| `[].domainBrowsing` | boolean | Always present — never `null` in practice, although the response schema allows it. |
| `[].status` | string | Whether the link is live. Write validation accepts only `Active` and `InActive` (parsed case-insensitively) and substitutes `InActive` when the field is omitted, so every record created or updated through the API carries one of those two values. `null` is possible on records created outside the API. **This endpoint does not filter on it** — `InActive` links come back in the same array as active ones, and suppressing them is your responsibility. |

## Sample response

```json title="200 OK"
[
  {
    "id": 12,
    "linkTypeId": 7,
    "description": "Book a swim lesson",
    "url": "https://example-leisure.co.uk/swim-lessons",
    "image": "https://cdn.example.com/public/EXAMPLETENANT/images/swim-tile.png",
    "targetType": "NewWindow",
    "domainBrowsing": true,
    "status": "Active"
  }
]
```

```json title="200 OK — link type exists but has no links"
[]
```

## Errors

| Status | Meaning | When |
|--------|---------|------|
| `400` | Bad request | `idType` was omitted or sent empty. The body is the plain string `Id Type query parameter is required.` This check runs before anything else, so it fires even when `{id}` is nonsense. |
| `400` | Bad request | `idType` was supplied but is not exactly `id` or `linkTypeId`. The body is the plain string `Provided idType query parameter is not valid.` Wrong casing, such as `ID` or `LinkTypeId`, lands here. |
| `400` | Bad request | The `{id}` route segment is not a valid 32-bit integer. The request is rejected before the lookup runs, and the body is a validation problem document (`application/problem+json`) with an `errors` map keyed by field name, rather than one of the plain strings above. |
| `404` | Not found | `idType=id` and no web link has that id. The body is the plain string `External Web Link Id '{id}' does not exist in database.` |
| `404` | Not found | `idType=linkTypeId` and no **link type** has that id. The body is the plain string `External Web Link Type Id '{id}' does not exist in database.` Note that a link type which exists but holds no links returns `200` with `[]` instead. |
| `500` | Internal server error | An unexpected server-side failure while reading. The response has no body, so there is nothing to parse. Retry, then raise a support ticket quoting the time of the call. |
