# Create topic

> POST /topics — create a subscription topic within a sending domain.

`POST /topics`

**Body parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Display name (max 255 chars). |
| `default_subscription` | string | Yes | The default subscription preference for new contacts: `opt_in` (every contact receives the topic unless they explicitly unsubscribe from it) or `opt_out` (no contact receives the topic unless they explicitly subscribe). **This value cannot be changed later.** |
| `visibility` | string | No | Visibility of the topic on the preference page: `public` (all contacts can see and toggle it) or `private` (only contacts already opted in can see it). Defaults to `private`. |
| `description` | string | No | Optional description shown on the preference page (max 200 chars). |
| `domain` | string | Yes | The sending domain this topic belongs to (one of your domains). Topic names are unique within a domain but freely reusable across domains. Passing `audience_id` is no longer accepted — pass `domain`. |

**Node.js**

```js
import { SendPing } from 'sendping';

const mb = new SendPing('mb_xxxxxxxxx');

const { data, error } = await mb.topics.create({ "domain": "yourdomain.com", "name": "Product updates", "default_subscription": "opt_in" });
console.log({ data, error });
```

**Ruby**

```ruby
require "sendping"

SendPing.api_key = "mb_xxxxxxxxx"

SendPing::Topics.create({
  "domain": "yourdomain.com",
  "name": "Product updates",
  "default_subscription": "opt_in"
})
```

**PHP**

```php
<?php
require 'vendor/autoload.php';

use SendPing\SendPing;

$sendping = SendPing::client('mb_xxxxxxxxx');

$sendping->topics->create([
  'domain' => "yourdomain.com",
  'name' => "Product updates",
  'default_subscription' => "opt_in"
]);
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Topics.create({
  "domain": "yourdomain.com",
  "name": "Product updates",
  "default_subscription": "opt_in"
})
```

**Go**

```go
import "github.com/shekhu10/sendping-sdks/sendping-go"

client := sendping.NewClient("mb_xxxxxxxxx")

topic, err := client.Topics.Create(&sendping.CreateTopicRequest{
    Domain:              "yourdomain.com",
    Name:                "Product updates",
    DefaultSubscription: "opt_in",
})
```

**Rust**

```rust
use sendping::{CreateTopicOptions, SendPing, SubscriptionState};

let mb = SendPing::new("mb_xxxxxxxxx");

let params = CreateTopicOptions::new(
    "yourdomain.com",
    "Product updates",
    SubscriptionState::OptIn,
);
let _topic = mb.topics.create(params).await?;
```

**Java**

```java
import co.sendping.SendPing;
import co.sendping.SendPingResponse;
import co.sendping.requests.CreateTopicRequest;

SendPing sendping = new SendPing("mb_xxxxxxxxx");

CreateTopicRequest request = CreateTopicRequest.builder()
        .domain("yourdomain.com")
        .name("Product updates")
        .defaultSubscription("opt_in")
        .build();

SendPingResponse response = sendping.topics().create(request);
```

**.NET**

```csharp
using SendPing;

ISendPing sendping = SendPingClient.Create("mb_xxxxxxxxx");

var resp = await sendping.TopicCreateAsync(new TopicCreateOptions
{
    Domain = "yourdomain.com",
    Name = "Product updates",
    DefaultSubscription = "opt_in",
});
```

**cURL**

```bash
curl -X POST 'https://www.sendping.co/api/topics' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{ "domain": "yourdomain.com", "name": "Product updates", "default_subscription": "opt_in" }'
```

**CLI**

```bash
sendping topics create \
  --domain 'yourdomain.com' \
  --name 'Product updates' \
  --default-subscription 'opt_in'
```

```json
{
  "object": "topic",
  "id": "topic_9a2f...",
  "audience_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "name": "Product updates",
  "description": null,
  "default_subscription": "opt_in",
  "visibility": "private",
  "created_at": "2026-06-25T10:00:00.000Z"
}
```
