# Portals API

The portals API endpoint lets you create and manage [portals](/docs/apis/graphql/portals) in your Buildkite organization.

## Portals

Portals provide restricted GraphQL API access to the Buildkite platform by defining stored GraphQL operations accessible through authenticated URL endpoints.

### Portal data model



| `uuid` | UUID of the portal |
| --- | --- |
| `slug` | Slug of the portal, used in API URLs |
| `organization_uuid` | UUID of the organization |
| `name` | Name of the portal |
| `description` | Description of the portal |
| `query` | GraphQL query that the portal executes |
| `allowed_ip_addresses` | Space-separated list of allowed IP addresses in CIDR notation |
| `user_invokable` | Whether users can invoke the portal |
| `created_at` | When the portal was created |
| `created_by` | User who created the portal |
| `token` | Plaintext portal token. Only returned when creating a portal. |



> 📘 Portal token
> The `token` field is only present in the response when creating a portal. Store it securely, as it cannot be retrieved again.

### List portals

Returns a [paginated list](/docs/rest-api#pagination) of an organization's portals.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/portals"
```

```json
[
  {
    "uuid": "01234567-89ab-cdef-0123-456789abcdef",
    "slug": "trigger-main-build",
    "organization_uuid": "f02d6a6f-7a0e-481d-9d6d-89b427aec48d",
    "name": "Trigger main build",
    "description": "Triggers a build on the main branch",
    "query": "mutation triggerBuild { buildCreate(input: { branch: \"main\", commit: \"HEAD\", pipelineID: \"UGlwZWxpbmUtLS0x\" }) { build { url } } }",
    "created_at": "2024-08-26T03:22:45.555Z",
    "created_by": {
      "id": "3d3c3bf0-7d58-4afe-8fe7-b3017d5504de",
      "graphql_id": "VXNlci0tLTNkM2MzYmYwLTdkNTgtNGFmZS04ZmU3LWIzMDE3ZDU1MDRkZQo=",
      "name": "Sam Kim",
      "email": "sam@example.com",
      "avatar_url": "https://www.gravatar.com/avatar/example",
      "created_at": "2013-08-29T10:10:03.000Z"
    },
    "allowed_ip_addresses": "192.0.2.1/32 198.51.100.0/24",
    "user_invokable": false
  }
]
```

Required scope: `read_portals`

Success response: `200 OK`

### Get a portal

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/portals/{portal.slug}"
```

```json
{
  "uuid": "01234567-89ab-cdef-0123-456789abcdef",
  "slug": "trigger-main-build",
  "organization_uuid": "f02d6a6f-7a0e-481d-9d6d-89b427aec48d",
  "name": "Trigger main build",
  "description": "Triggers a build on the main branch",
  "query": "mutation triggerBuild { buildCreate(input: { branch: \"main\", commit: \"HEAD\", pipelineID: \"UGlwZWxpbmUtLS0x\" }) { build { url } } }",
  "created_at": "2024-08-26T03:22:45.555Z",
  "created_by": {
    "id": "3d3c3bf0-7d58-4afe-8fe7-b3017d5504de",
    "graphql_id": "VXNlci0tLTNkM2MzYmYwLTdkNTgtNGFmZS04ZmU3LWIzMDE3ZDU1MDRkZQo=",
    "name": "Sam Kim",
    "email": "sam@example.com",
    "avatar_url": "https://www.gravatar.com/avatar/example",
    "created_at": "2013-08-29T10:10:03.000Z"
  },
  "allowed_ip_addresses": "192.0.2.1/32 198.51.100.0/24",
  "user_invokable": false
}
```

Required scope: `read_portals`

Success response: `200 OK`

### Create a portal

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X POST "https://api.buildkite.com/v2/organizations/{org.slug}/portals" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Trigger main build",
    "query": "mutation triggerBuild { buildCreate(input: { branch: \"main\", commit: \"HEAD\", pipelineID: \"UGlwZWxpbmUtLS0x\" }) { build { url } } }"
  }'
```

```json
{
  "uuid": "01234567-89ab-cdef-0123-456789abcdef",
  "slug": "trigger-main-build",
  "organization_uuid": "f02d6a6f-7a0e-481d-9d6d-89b427aec48d",
  "name": "Trigger main build",
  "description": null,
  "query": "mutation triggerBuild { buildCreate(input: { branch: \"main\", commit: \"HEAD\", pipelineID: \"UGlwZWxpbmUtLS0x\" }) { build { url } } }",
  "created_at": "2024-08-26T03:22:45.555Z",
  "created_by": {
    "id": "3d3c3bf0-7d58-4afe-8fe7-b3017d5504de",
    "graphql_id": "VXNlci0tLTNkM2MzYmYwLTdkNTgtNGFmZS04ZmU3LWIzMDE3ZDU1MDRkZQo=",
    "name": "Sam Kim",
    "email": "sam@example.com",
    "avatar_url": "https://www.gravatar.com/avatar/example",
    "created_at": "2013-08-29T10:10:03.000Z"
  },
  "allowed_ip_addresses": null,
  "user_invokable": false,
  "token": "xxx-yyy-zzz"
}
```

Required [request body properties](/docs/api#request-body-properties):



| `name` | Name for the portal. _Example:_ `"Trigger main build"` |
| --- | --- |
| `query` | GraphQL query that the portal executes. _Example:_ `"mutation triggerBuild { buildCreate(input: { branch: \"main\", pipelineID: \"abc123\" }) { build { url } } }"` |



[Request body properties](/docs/api#request-body-properties):



| `slug` | Slug for the portal. Auto-generated from the name if not provided. _Example:_ `"trigger-main-build"` |
| --- | --- |
| `description` | Description for the portal. _Example:_ `"Triggers a build on the main branch"` |
| `allowed_ip_addresses` | Space-separated list of allowed IP addresses in CIDR notation. _Example:_ `"192.0.2.1/32 198.51.100.0/24"` |
| `user_invokable` | Whether users can invoke the portal. _Example:_ `false` |



Required scope: `write_portals`

Success response: `201 Created`

Error responses:



| `422 Unprocessable Entity` | `{ "message": "Validation failed: Reason for failure" }` |
| --- | --- |



### Update a portal

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X PUT "https://api.buildkite.com/v2/organizations/{org.slug}/portals/{portal.slug}" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Trigger main build" }'
```

```json
{
  "uuid": "01234567-89ab-cdef-0123-456789abcdef",
  "slug": "trigger-main-build",
  "organization_uuid": "f02d6a6f-7a0e-481d-9d6d-89b427aec48d",
  "name": "Trigger main build",
  "description": "Triggers a build on the main branch",
  "query": "mutation triggerBuild { buildCreate(input: { branch: \"main\", commit: \"HEAD\", pipelineID: \"UGlwZWxpbmUtLS0x\" }) { build { url } } }",
  "created_at": "2024-08-26T03:22:45.555Z",
  "created_by": {
    "id": "3d3c3bf0-7d58-4afe-8fe7-b3017d5504de",
    "graphql_id": "VXNlci0tLTNkM2MzYmYwLTdkNTgtNGFmZS04ZmU3LWIzMDE3ZDU1MDRkZQo=",
    "name": "Sam Kim",
    "email": "sam@example.com",
    "avatar_url": "https://www.gravatar.com/avatar/example",
    "created_at": "2013-08-29T10:10:03.000Z"
  },
  "allowed_ip_addresses": "192.0.2.1/32 198.51.100.0/24",
  "user_invokable": false
}
```

Optional [request body properties](/docs/api#request-body-properties):



| `name` | Name for the portal. _Example:_ `"Trigger main build"` |
| --- | --- |
| `slug` | Slug for the portal. _Example:_ `"trigger-main-build"` |
| `description` | Description for the portal. _Example:_ `"Triggers a build on the main branch"` |
| `query` | GraphQL query that the portal executes. _Example:_ `"mutation triggerBuild { buildCreate(input: { branch: \"main\", pipelineID: \"abc123\" }) { build { url } } }"` |
| `allowed_ip_addresses` | Space-separated list of allowed IP addresses in CIDR notation. _Example:_ `"192.0.2.1/32 198.51.100.0/24"` |
| `user_invokable` | Whether users can invoke the portal. _Example:_ `false` |



Required scope: `write_portals`

Success response: `200 OK`

Error responses:



| `422 Unprocessable Entity` | `{ "message": "Validation failed: Reason for failure" }` |
| --- | --- |



### Delete a portal

Delete a portal.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://api.buildkite.com/v2/organizations/{org.slug}/portals/{portal.slug}"
```

Required scope: `write_portals`

Success response: `204 No Content`

Error responses:



| `422 Unprocessable Entity` | `{ "message": "Reason the portal couldn't be deleted" }` |
| --- | --- |


