# Tailnet creation API

Last validated Jan 5, 2026

> **Note:** Tailnet creation APIs are currently in alpha.

> **Warning:**
>
> You must receive approval from Tailscale to use these private APIs. Contact your account team or partnership manager for more information.

Tailscale provides API endpoints that you can use to create and list multiple Tailscale networks (known as tailnets) in your organization. These tailnets are considered **API-only**, meaning that they do not contain human users or appear in the admin console. As a result, tailnets created with these APIs are great for building directly into your applications and infrastructure, but are not appropriate for use cases that require a human to join the tailnet directly.

## Authentication

You can only authenticate these tailnet creation APIs with an [OAuth client][kb-oauth-client]. You must create the OAuth client in an existing tailnet that's pre-approved to use these APIs.

1. Generate an OAuth client with the `tailnets` scope.
2. [Exchange the OAuth client secret for an API access token][kb-exchange-token] that can be provided to the API endpoints.

### Authenticate against API-only tailnets

When you [create][ar-create-tailnet] a new API-only tailnet, the [response][ar-create-tailnet-response] contains details for an OAuth client that permits access to the API for that tailnet.

Additionally, an OAuth client in the creating tailnet can obtain an OAuth access token with access to the API-only tailnet by specifying the tailnet's ID in the `tailnet` parameter to our `/token` endpoint. The OAuth client must have the `all` scope.

For example:

```shell
 curl -d "client_id=${OAUTH_CLIENT_ID}" -d "client_secret=${OAUTH_CLIENT_SECRET}" \
     "https://api.tailscale.com/api/v2/oauth/token?tailnet=T123456CNTRL"
```

## Endpoints

### Create a new tailnet

#### Request

```shell
curl https://api.tailscale.com/api/v2/organizations/-/tailnets \
  --request POST \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --data '{"displayName": "<displayName>"}'
```

* `displayName`: A custom name for the tailnet that you provide. It can contain letters, numbers, spaces, apostrophes, and hyphens. This name must be unique within your organization.

#### Response

```json
{
  "id": "T123456CNTRL",
  "displayName": "<displayName>",
  "orgId": "o123456CNTRL",
  "dnsName": "tail1234.ts.net",
  "createdAt": "2025-01-01T12:00:00Z",
  "oauthClient": {
    "id": "k123456CNTRL",
    "secret": "tskey-client-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}
```

* `id`: A stable, globally-unique identifier for the tailnet.
* `displayName`: The tailnet name you provided.
* `orgId`: A stable, globally-unique identifier for your organization.
* `dnsName`: The DNS suffix used to construct fully qualified domain names for devices in this tailnet.
* `createdAt`: When the tailnet was created, represented as an [ISO 8601][xt-datetime] `datetime` string.
* `oauthClient`: An OAuth client with the `all` scope that permits changing the new tailnet's settings or authenticating devices to the tailnet using our public API. If you lose this, or want to create additional credentials for the API-only tailnet, you can [authenticate against the API-only tailnet][ar-authenticate-api-only] using an OAuth client from the creating tailnet, then use it to [create a new OAuth client][co-api-create-key] in the API-only tailnet.

### Delete an API-driven tailnet

Once you've created an API-driven tailnet, you can delete it using that tailnet's OAuth client. You need to [exchange][kb-exchange-token] the `oauthClient.secret` from the above response for an API access token specific to the tailnet that you want to delete. You can also [authenticate against the API-only tailnet][ar-authenticate-api-only] using an OAuth client from the creating tailnet.

#### Request

```shell
curl https://api.tailscale.com/api/v2/tailnet/- \
  --request DELETE \
  --header 'Authorization: Bearer TAILNET_SPECIFIC_ACCESS_TOKEN'
```

### Get all tailnets

#### Request

```shell
curl https://api.tailscale.com/api/v2/organizations/-/tailnets \
  --request GET \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```

#### Response

The endpoint returns a `tailnets` object containing an array of all the tailnets in your organization. This will include your original tailnet as well as any tailnets created with these API endpoints.

```json
{
  "tailnets": [
    {
      "id": "T123456CNTRL",
      "displayName": "<displayName>",
      "orgId": "o123456CNTRL",
      "createdAt": "2025-01-01T12:00:00Z"
    }
  ]
}
```

* `id`: A stable, globally-unique identifier for the tailnet.
* `displayName`: The tailnet name you provided.
* `orgId`: A stable, globally-unique identifier for your organization.
* `createdAt`: When the tailnet was created, represented as an [ISO 8601][xt-datetime] `datetime` string.

## Limitations

* These alpha endpoints are not considered stable interfaces. Tailscale will communicate with users before making breaking changes.
* These alpha endpoints are private and are therefore not available in our API's Go client, Terraform provider, or Pulumi provider.
* Tailnets created with these API endpoints have no human owner or users. You must use the public API to interact with the tailnet. Future iterations of this feature will remove this limitation.
* Tailnets created with these API endpoints do not appear in the admin console for your organization. Future iterations of this feature will let you choose if these tailnets should appear in the admin console.

[ar-authenticate-api-only]: #authenticate-against-api-only-tailnets

[ar-create-tailnet]: #create-a-new-tailnet

[ar-create-tailnet-response]: #response

[co-api-create-key]: /api#tag/keys/post/tailnet/{tailnet}/keys

[kb-exchange-token]: /docs/features/oauth-clients#verifying-you-can-generate-api-access-tokens

[kb-oauth-client]: /docs/features/oauth-clients

[xt-datetime]: https://en.wikipedia.org/wiki/ISO_8601
