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

# Relatie toevoegen

POST https://api.laposta.nl/v2/member
Content-Type: application/x-www-form-urlencoded

Voegt een relatie toe aan een lijst. Naast het e-mailadres is het IP-adres verplicht, want daarmee leg je vast waar de aanmelding vandaan komt. Eigen velden geef je mee in `custom_fields`, met de `custom_name` van het veld als sleutel.Bestaat het adres al in de lijst, dan volgt een foutmelding, tenzij je `options[upsert]` op `true` zet.Adds a subscriber to a list. Besides the email address, the IP address is required, as this records where the signup came from. You pass custom fields in `custom_fields`, using the `custom_name` of the field as the key.If the address already exists in the list, an error message is returned, unless you set `options[upsert]` to `true`.Fügt einer Liste einen Abonnenten hinzu. Neben der E-Mail-Adresse ist die IP-Adresse Pflicht, denn damit hältst du fest, woher die Anmeldung kommt. Eigene Felder gibst du in `custom_fields` mit, mit dem `custom_name` des Feldes als Schlüssel.Existiert die Adresse bereits in der Liste, folgt eine Fehlermeldung, es sei denn, du setzt `options[upsert]` auf `true`.Añade un contacto a una lista. Además de la dirección de correo electrónico, la dirección IP es obligatoria, porque con ella registras de dónde procede el registro. Los campos adicionales los envías en `custom_fields`, con el `custom_name` del campo como clave.Si la dirección ya existe en la lista, recibes un mensaje de error, salvo que pongas `options[upsert]` en `true`.

Reference: https://docs.laposta.org/relaties/relatie-toevoegen

## Authentication

- `Authorization` header (basic auth, required) — Vul je API-sleutel in bij `api_key` en laat `leave_empty` leeg. De API gebruikt basic auth, waarbij je sleutel de plaats van de gebruikersnaam inneemt. In curl schrijf je dat als `-u JOUW_SLEUTEL:`, met een dubbele punt en niets erachter.Enter your API key at `api_key` and leave `leave_empty` empty. The API uses basic auth, with your key in place of the username. In curl that reads `-u YOUR_KEY:`, with a colon and nothing after it.Trage deinen API-Schlüssel bei `api_key` ein und lass `leave_empty` leer. Die API nutzt Basic Auth, wobei dein Schlüssel an die Stelle des Benutzernamens tritt. In curl schreibst du das als `-u DEIN_SCHLUESSEL:`, mit einem Doppelpunkt und nichts dahinter.Introduce tu clave API en `api_key` y deja `leave_empty` vacío. La API usa basic auth, con tu clave en lugar del nombre de usuario. En curl se escribe como `-u TU_CLAVE:`, con dos puntos y nada después.

## Request

### Body (application/x-www-form-urlencoded)

This endpoint expects an object.

- `list_id` (string, required) — Het id van de lijst. Dat vind je in het antwoord van [Alle lijsten opvragen](/lijsten/alle-lijsten-opvragen), en in de applicatie in de URL van de lijst.The id of the list. You find it in the response of [Get all lists](/lijsten/alle-lijsten-opvragen), and in the application in the URL of the list.Die ID der Liste. Du findest sie in der Antwort von [Alle Listen abrufen](/lijsten/alle-lijsten-opvragen) und in der Anwendung in der URL der Liste.El id de la lista. Lo encuentras en la respuesta de [Obtener todas las listas](/lijsten/alle-lijsten-opvragen) y en la aplicación, en la URL de la lista.
- `ip` (string, required) — Het IP-adres waarvandaan de aanmelding kwam. Bij een formulier op je site is dat het adres van de bezoeker, niet dat van je server.The IP address the sign-up came from. For a form on your site that is the visitor address, not your server address.Die IP-Adresse, von der die Anmeldung kam. Bei einem Formular auf deiner Website ist das die Adresse des Besuchers, nicht die deines Servers.La dirección IP desde la que llegó el registro. En un formulario de tu web es la dirección del visitante, no la de tu servidor.
- `email` (string, required) — Het e-mailadres van de toe te voegen relatie.The email address of the subscriber to be addedDie E-Mail-Adresse des hinzuzufügenden Abonnenten.La dirección de correo electrónico del contacto que se va a añadir.
- `source_url` (string, optional) — De URL vanwaar de relatie is aangemeld.The URL from which the subscriber is registeredDie URL, von der aus der Abonnent angemeldet wurde.La URL desde la que se ha registrado el contacto.
- `custom_fields` (MemberPostRequestBodyContentApplicationXWwwFormUrlencodedSchemaCustomFields, optional) — De waardes van de extra aangemaakte velden. De naam (de key) van het veld moet de 'custom_name' zijn (onderdeel van het Field object). Dit is gelijk aan de 'Relatievariabele' in de applicatie. Labels geef je mee als reeks, met vierkante haken: custom_fields[labels][]=Klant. Zonder die haken slaagt de aanroep wel maar verandert er niets, en een label dat de lijst niet heeft geeft foutcode 203.The values of the extra fields. The name (key) of the field is the 'custom_name' (part of the Field object). This is the same as the 'Variable' in the application. You pass labels as an array, with square brackets: custom_fields[labels][]=Customer. Without those brackets the call still succeeds but nothing changes, and a label that the list does not have returns error code 203.Die Werte der zusätzlich angelegten Felder. Der Name (der key) des Feldes muss der 'custom_name' sein (Teil des Field-Objekts). Das entspricht der 'Abonnentenvariable' in der Anwendung. Labels werden als Array übergeben, mit eckigen Klammern: custom_fields[labels][]=Kunde. Ohne diese Klammern gelingt der Aufruf zwar, es ändert sich aber nichts, und ein Label, das die Liste nicht hat, liefert den Fehlercode 203.Los valores de los campos adicionales creados. El nombre (la key) del campo debe ser el 'custom_name' (parte del objeto Field). Esto equivale a la 'variable de contacto' en la aplicación. Las etiquetas las pasas como array, con corchetes: custom_fields[labels][]=Cliente. Sin esos corchetes la llamada funciona pero no cambia nada, y una etiqueta que la lista no tiene devuelve el código de error 203.
- `options` (list of string, optional) — Extra aanwijzingen, mogelijkheden zijn: upsert: true om velden te overschrijven als het e-mailadres al aan een actieve relatie van deze lijst gekoppeld is. Normaal gesproken zou je een foutmelding krijgen als het e-mailadres al gekoppeld is aan een actieve relatie. Let op: Als een relatie uitgeschreven is en je doet een upsert met dat e-mailadres, dan wordt deze weer op actief gezet. Indien je wilt voorkomen dat een uitgeschreven relatie weer actief wordt, kun je de optie suppress_reactivation gebruiken. suppress_reactivation: true om te voorkomen dat een uitgeschreven relatie weer op actief wordt gezet bij een upsert suppress_email_notification: true om te voorkomen dat bij elke aanmelding via een api een notificatiemailtje wordt verstuurd ignore_doubleoptin: true om relaties bij een double-optin lijst meteen actief te maken en ervoor te zorgen dat er geen bevestigingsmail wordt verstuurd bij een aanmelding via de api.Additional instructions, with possibilities being: upsert: true to overwrite fields if the email address is already linked to an active contact in this list. Normally, you would receive an error if the email address is already linked to an active contact. Note: If a subscriber is unsubscribed and you perform an upsert with that email address, it will be set to active again. If you want to prevent an unsubscribed subscriber from being reactivated, you can use the suppress_reactivation option. suppress_reactivation: true to prevent an unsubscribed subscriber from being reactivated during an upsert suppress_email_notification: true to prevent a notification email from being sent every time someone logs in via an API ignore_doubleoptin: true to instantly activate subscribers on a double-optin list and ensure that no confirmation email is sent when signing up through the API.Zusätzliche Anweisungen, mögliche Optionen sind: upsert: true, um Felder zu überschreiben, wenn die E-Mail-Adresse bereits mit einem aktiven Abonnenten dieser Liste verknüpft ist. Normalerweise würdest du eine Fehlermeldung bekommen, wenn die E-Mail-Adresse schon mit einem aktiven Abonnenten verknüpft ist. Achtung: Wenn ein Abonnent abgemeldet ist und du machst einen upsert mit dieser E-Mail-Adresse, wird er wieder auf aktiv gesetzt. Wenn du verhindern willst, dass ein abgemeldeter Abonnent wieder aktiv wird, kannst du die Option suppress_reactivation verwenden. suppress_reactivation: true, um zu verhindern, dass ein abgemeldeter Abonnent bei einem upsert wieder auf aktiv gesetzt wird suppress_email_notification: true, um zu verhindern, dass bei jeder Anmeldung über eine API eine Benachrichtigungsmail versendet wird ignore_doubleoptin: true, um Abonnenten bei einer Double-Optin-Liste sofort aktiv zu machen und dafür zu sorgen, dass bei einer Anmeldung über die API keine Bestätigungsmail versendet wird.Instrucciones adicionales, las posibilidades son: upsert: true para sobrescribir campos si la dirección de correo electrónico ya está vinculada a un contacto activo de esta lista. Normalmente recibirías un mensaje de error si la dirección de correo electrónico ya está vinculada a un contacto activo. Ten en cuenta lo siguiente: si un contacto está dado de baja y haces un upsert con esa dirección de correo electrónico, se vuelve a poner como activo. Si quieres evitar que un contacto dado de baja vuelva a estar activo, puedes usar la opción suppress_reactivation. suppress_reactivation: true para evitar que un contacto dado de baja se vuelva a poner como activo en un upsert suppress_email_notification: true para evitar que se envíe un correo de notificación en cada registro a través de una api ignore_doubleoptin: true para activar de inmediato los contactos de una lista con double-optin y evitar que se envíe un correo de confirmación en un registro a través de la api.

## Response

### 201

De aanvraag is gelukt.The request succeeded.Die Anfrage war erfolgreich.La solicitud se ha realizado correctamente.

- `member` (Member, optional) — Het member-objectThe member objectDas member-ObjektEl objeto member

## Errors

### 400 Bad Request Error

De aanvraag klopt niet. Het antwoord bevat een `type`, een `message` en meestal een `code` en de `parameter` die de fout veroorzaakte. Een object dat niet bestaat valt ook hieronder, met code 203.The request is not valid. The response contains a `type`, a `message` and usually a `code` plus the `parameter` that caused it. An object that does not exist also falls under this, with code 203.Die Anfrage stimmt nicht. Die Antwort enthält einen `type`, eine `message` und meistens einen `code` und den `parameter`, der den Fehler verursacht hat. Ein Objekt, das nicht existiert, fällt ebenfalls hierunter, mit Code 203.La solicitud no es correcta. La respuesta contiene un `type`, un `message` y normalmente un `code` y el `parameter` que ha causado el error. Un objeto que no existe también entra aquí, con el código 203.

- `error` (ErrorError, optional)

### 401 Unauthorized Error

Er is geen geldige API-sleutel meegestuurd, of dit endpoint staat niet aan voor dit account.No valid API key was provided, or this endpoint is not enabled for this account.Es wurde kein gültiger API-Schlüssel mitgeschickt, oder dieser Endpunkt ist für dieses Konto nicht aktiv.No se ha enviado una clave API válida, o este endpoint no está activado para esta cuenta.

- `error` (ErrorError, optional)

### 429 Too Many Requests Error

Je hebt te veel aanvragen in een minuut gedaan. De header `Retry-After` vertelt na hoeveel seconden het weer mag.Too many requests in one minute. The `Retry-After` header tells you how many seconds to wait.Du hast zu viele Anfragen in einer Minute gestellt. Der Header `Retry-After` sagt, nach wie vielen Sekunden es wieder erlaubt ist.Has hecho demasiadas solicitudes en un minuto. La cabecera `Retry-After` indica después de cuántos segundos puedes volver a intentarlo.

- `error` (ErrorError, optional)

## Types

### MemberPostRequestBodyContentApplicationXWwwFormUrlencodedSchemaCustomFields

De waardes van de extra aangemaakte velden. De naam (de key) van het veld moet de 'custom_name' zijn (onderdeel van het Field object). Dit is gelijk aan de 'Relatievariabele' in de applicatie. Labels geef je mee als reeks, met vierkante haken: custom_fields[labels][]=Klant. Zonder die haken slaagt de aanroep wel maar verandert er niets, en een label dat de lijst niet heeft geeft foutcode 203.The values of the extra fields. The name (key) of the field is the 'custom_name' (part of the Field object). This is the same as the 'Variable' in the application. You pass labels as an array, with square brackets: custom_fields[labels][]=Customer. Without those brackets the call still succeeds but nothing changes, and a label that the list does not have returns error code 203.Die Werte der zusätzlich angelegten Felder. Der Name (der key) des Feldes muss der 'custom_name' sein (Teil des Field-Objekts). Das entspricht der 'Abonnentenvariable' in der Anwendung. Labels werden als Array übergeben, mit eckigen Klammern: custom_fields[labels][]=Kunde. Ohne diese Klammern gelingt der Aufruf zwar, es ändert sich aber nichts, und ein Label, das die Liste nicht hat, liefert den Fehlercode 203.Los valores de los campos adicionales creados. El nombre (la key) del campo debe ser el 'custom_name' (parte del objeto Field). Esto equivale a la 'variable de contacto' en la aplicación. Las etiquetas las pasas como array, con corchetes: custom_fields[labels][]=Cliente. Sin esos corchetes la llamada funciona pero no cambia nada, y una etiqueta que la lista no tiene devuelve el código de error 203.

### Member

Het member-objectThe member objectDas member-ObjektEl objeto member

- `member_id` (string, optional) — Het id van dit member object.The ID of this member objectDie ID dieses member-Objekts.El ID de este objeto member.
- `list_id` (string, optional) — Het id van de bijbehorende lijst.The ID of the related listDie ID der zugehörigen Liste.El ID de la lista correspondiente.
- `email` (string, optional) — Het e-mail adres.The email addressDie E-Mail-Adresse.La dirección de correo electrónico.
- `state` (enum, optional) — De huidige status van deze relatie: active, unsubscribed, unconfirmed of cleaned.The current status of this subscriber: active, unsubscribed, unconfirmed or cleanedDer aktuelle Status dieses Abonnenten: active, unsubscribed, unconfirmed oder cleaned.El estado actual de este contacto: active, unsubscribed, unconfirmed o cleaned.
  - Allowed values: `active`, `deleted`
- `timezone` (string, optional) — De tijdzone van het account voor datum- en tijdvelden.The account timezone used for datetime fieldsDie Zeitzone des Kontos für Datums- und Zeitfelder.La zona horaria de la cuenta para los campos de fecha y hora.
- `signup_date` (string, optional) — Moment van aanmelding.Date and time of subscriptionZeitpunkt der Anmeldung.Momento del registro.
- `signup_date_iso` (string, optional, nullable) — Moment van aanmelding in ISO-formaat.Date and time of subscription in ISO formatZeitpunkt der Anmeldung im ISO-Format.Momento del registro en formato ISO.
- `modified` (string, optional, nullable) — Moment van laatste wijziging.Date and time of last modification madeZeitpunkt der letzten Änderung.Momento de la última modificación.
- `modified_iso` (string, optional, nullable) — Moment van laatste wijziging in ISO-formaat.Date and time of last modification in ISO formatZeitpunkt der letzten Änderung im ISO-Format.Momento de la última modificación en formato ISO.
- `confirm_date` (string, optional, nullable) — Moment van bevestiging.Date and time of confirmationZeitpunkt der Bestätigung.Momento de la confirmación.
- `confirm_date_iso` (string, optional, nullable) — Moment van bevestiging in ISO-formaat.Date and time of confirmation in ISO formatZeitpunkt der Bestätigung im ISO-Format.Momento de la confirmación en formato ISO.
- `ip` (string, optional) — Het IP-adres waarvandaan de relatie zich heeft aangemeld.IP from which the subscriber is registeredDie IP-Adresse, von der aus sich der Abonnent angemeldet hat.La dirección IP desde la que se ha registrado el contacto.
- `source_url` (string, optional) — De pagina waarvandaan de relatie zich heeft aangemeld.URL from which the subscriber is registeredDie Seite, von der aus sich der Abonnent angemeldet hat.La página desde la que se ha registrado el contacto.
- `custom_fields` (MemberCustomFields, optional) — De waarden van de eigen velden van de lijst, met de `custom_name` van elk veld als sleutel. Heeft de lijst labels, dan staat daar `labels` bij, met de labels van deze relatie als array.An array with the value of all additional fields of the corresponding list. If there are fields where several options can be selected, these options are listed in an array. If the list has labels, `labels` is included as well, with the labels of that subscriber as an array.Die Werte der eigenen Felder der Liste, mit dem `custom_name` jedes Feldes als Schlüssel. Hat die Liste Labels, dann steht dort auch `labels`, mit den Labels dieses Abonnenten als Array.Los valores de los campos adicionales de la lista, con el `custom_name` de cada campo como clave. Si la lista tiene etiquetas, ahí aparece también `labels`, con las etiquetas de este contacto como array.

### ErrorError

- `type` (enum, required)
  - Allowed values: `invalid_request`, `invalid_input`, `internal`
- `message` (string, required)
- `code` (integer, optional)
- `parameter` (string, optional)

### MemberCustomFields

De waarden van de eigen velden van de lijst, met de `custom_name` van elk veld als sleutel. Heeft de lijst labels, dan staat daar `labels` bij, met de labels van deze relatie als array.An array with the value of all additional fields of the corresponding list. If there are fields where several options can be selected, these options are listed in an array. If the list has labels, `labels` is included as well, with the labels of that subscriber as an array.Die Werte der eigenen Felder der Liste, mit dem `custom_name` jedes Feldes als Schlüssel. Hat die Liste Labels, dann steht dort auch `labels`, mit den Labels dieses Abonnenten als Array.Los valores de los campos adicionales de la lista, con el `custom_name` de cada campo como clave. Si la lista tiene etiquetas, ahí aparece también `labels`, con las etiquetas de este contacto como array.

## Examples

**Request**

```json
{
  "list_id": "BaImMu3JZA",
  "ip": "198.51.100.10",
  "email": "relatie@example.net"
}
```

**Response**

```json
{
  "member": {
    "member_id": "ZKfjhLJHfl",
    "list_id": "BaImMu3JZA",
    "email": "relatie@example.net",
    "state": "active",
    "timezone": "Europe/Amsterdam",
    "signup_date": "string",
    "signup_date_iso": "string",
    "modified": "string",
    "modified_iso": "string",
    "confirm_date": "string",
    "confirm_date_iso": "string",
    "ip": "string",
    "source_url": "string",
    "custom_fields": {}
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.laposta.nl/v2/member"

payload = ""
headers = {
    "Content-Type": "application/x-www-form-urlencoded"
}

response = requests.post(url, data=payload, headers=headers, auth=("<api_key>", "<leave_empty>"))

print(response.json())
```

```javascript
const url = 'https://api.laposta.nl/v2/member';
const credentials = btoa("<api_key>:<leave_empty>");

const options = {
  method: 'POST',
  headers: {
    Authorization: `Basic ${credentials}`,
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams('')
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

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

func main() {

	url := "https://api.laposta.nl/v2/member"

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

	req.SetBasicAuth("<api_key>", "<leave_empty>")
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	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.laposta.nl/v2/member")

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

request = Net::HTTP::Post.new(url)
request.basic_auth("<api_key>", "<leave_empty>")
request["Content-Type"] = 'application/x-www-form-urlencoded'

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.laposta.nl/v2/member")
  .basicAuth("<api_key>", "<leave_empty>")
  .header("Content-Type", "application/x-www-form-urlencoded")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.laposta.nl/v2/member', [
  'form_params' => null,
  'headers' => [
    'Content-Type' => 'application/x-www-form-urlencoded',
  ],
    'auth' => ['<api_key>', '<leave_empty>'],
]);

echo $response->getBody();
```

```csharp
using RestSharp;
using RestSharp.Authenticators;

var client = new RestClient("https://api.laposta.nl/v2/member");
client.Authenticator = new HttpBasicAuthenticator("<api_key>", "<leave_empty>");
var request = new RestRequest(Method.POST);

request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let credentials = Data("<api_key>:<leave_empty>".utf8).base64EncodedString()

let headers = [
  "Authorization": "Basic \(credentials)",
  "Content-Type": "application/x-www-form-urlencoded"
]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.laposta.nl/v2/member")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

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()
```