> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.brevo.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.brevo.com/_mcp/server.

# Create Contact via DOI (Double-Opt-In) Flow

POST https://api.brevo.com/v3/contacts/doubleOptinConfirmation
Content-Type: application/json

attributes param in this endpoint is an object containing key-value pairs where values can be either a string, integer, array, or boolean. You can create key-value pairs with these four datatypes. When a value is an array, it should be an array of strings.

Reference: https://developers.brevo.com/reference/create-doi-contact

## Authentication

- `api-key` header (required) — The API key should be passed in the request headers as `api-key` for authentication.

## Request

### Body (application/json)

- `email` (string, required) — Email address where the confirmation email will be sent. This email address will be the identifier for all other contact attributes.
- `includeListIds` (list of long, required) — Lists under user account where contact should be added
- `redirectionUrl` (string, required) — URL of the web page that user will be redirected to after clicking on the double opt in URL. When editing your DOI template you can reference this URL by using the tag **\{\{ params.DOIurl }}**.
- `templateId` (long, required) — Id of the Double opt-in (DOI) template
- `attributes` (map from string to double or string or boolean or list of string, optional) — Pass the set of attributes and their values. **These attributes must be present in your Brevo account**. For eg. **\{'FNAME':'Elly', 'LNAME':'Roger', 'COUNTRIES': \['India','China']}**
- `excludeListIds` (list of long, optional) — Lists under user account where contact should not be added

## Response

### 201

DOI Contact created

## Examples

**Request**

```json
{
  "email": "elly@example.com",
  "includeListIds": [
    36
  ],
  "redirectionUrl": "http://requestb.in/173lyyx1",
  "templateId": 2
}
```

**Response**

```json
{}
```

**SDK Code**

```typescript
import { BrevoClient } from "@getbrevo/brevo";

async function main() {
    const client = new BrevoClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.contacts.createDoiContact({
        email: "elly@example.com",
        includeListIds: [
            36,
        ],
        redirectionUrl: "http://requestb.in/173lyyx1",
        templateId: 2,
    });
}
main();

```

```python
from brevo import Brevo

client = Brevo(
    api_key="YOUR_API_KEY_HERE",
)

client.contacts.create_doi_contact(
    email="elly@example.com",
    include_list_ids=[
        36
    ],
    redirection_url="http://requestb.in/173lyyx1",
    template_id=2,
)

```

```php
<?php

namespace Example;

use Brevo\Brevo;
use Brevo\Contacts\Requests\CreateDoiContactRequest;

$client = new Brevo(
    apiKey: 'YOUR_API_KEY_HERE',
);
$client->contacts->createDoiContact(
    new CreateDoiContactRequest([
        'email' => 'elly@example.com',
        'includeListIds' => [
            36,
        ],
        'redirectionUrl' => 'http://requestb.in/173lyyx1',
        'templateId' => 2,
    ]),
);

```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.brevo.com/v3/contacts/doubleOptinConfirmation"

	payload := strings.NewReader("{\n  \"email\": \"elly@example.com\",\n  \"includeListIds\": [\n    36\n  ],\n  \"redirectionUrl\": \"http://requestb.in/173lyyx1\",\n  \"templateId\": 2\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("api-key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.brevo.com/v3/contacts/doubleOptinConfirmation")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["api-key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"email\": \"elly@example.com\",\n  \"includeListIds\": [\n    36\n  ],\n  \"redirectionUrl\": \"http://requestb.in/173lyyx1\",\n  \"templateId\": 2\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.brevo.com/v3/contacts/doubleOptinConfirmation")
  .header("api-key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"email\": \"elly@example.com\",\n  \"includeListIds\": [\n    36\n  ],\n  \"redirectionUrl\": \"http://requestb.in/173lyyx1\",\n  \"templateId\": 2\n}")
  .asString();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.brevo.com/v3/contacts/doubleOptinConfirmation");
var request = new RestRequest(Method.POST);
request.AddHeader("api-key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"email\": \"elly@example.com\",\n  \"includeListIds\": [\n    36\n  ],\n  \"redirectionUrl\": \"http://requestb.in/173lyyx1\",\n  \"templateId\": 2\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "api-key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "email": "elly@example.com",
  "includeListIds": [36],
  "redirectionUrl": "http://requestb.in/173lyyx1",
  "templateId": 2
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.brevo.com/v3/contacts/doubleOptinConfirmation")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```