package main
import (
"context"
"fmt"
"log"
"os"
"github.com/AhaSend/ahasend-go"
"github.com/AhaSend/ahasend-go/api"
"github.com/AhaSend/ahasend-go/models/requests"
"github.com/google/uuid"
)
func main() {
client := api.NewAPIClient(api.WithAPIKey(os.Getenv("AHASEND_API_KEY")))
accountID := uuid.MustParse(os.Getenv("AHASEND_ACCOUNT_ID"))
ctx := context.Background()
// Only the fields you set change. A nil attribute value deletes that key.
response, _, err := client.ContactsAPI.UpdateContact(ctx, accountID, "user+tag@example.com", requests.UpdateContactRequest{
FirstName: ahasend.String("Jordan"),
Attributes: map[string]any{"obsolete_key": nil},
})
if err != nil {
log.Fatalf("Error updating contact: %v", err)
}
fmt.Printf("Updated contact %s\n", response.ID)
}import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
const idOrEmail = "User+Tag@Example.COM";
const contact = await client.contacts.update(idOrEmail, {
unsubscribed: true,
attributes: { obsolete: null },
});
console.log("Contact updated.", { id: contact.id, unsubscribed: contact.unsubscribed });
curl --request PUT \
--url https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "jsmith@example.com",
"first_name": "<string>",
"last_name": "<string>",
"status_reason": "<string>",
"unsubscribed": true,
"attributes": {}
}
'import requests
url = "https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}"
payload = {
"email": "jsmith@example.com",
"first_name": "<string>",
"last_name": "<string>",
"status_reason": "<string>",
"unsubscribed": True,
"attributes": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'email' => 'jsmith@example.com',
'first_name' => '<string>',
'last_name' => '<string>',
'status_reason' => '<string>',
'unsubscribed' => true,
'attributes' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}HttpResponse<String> response = Unirest.put("https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"jsmith@example.com\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"status_reason\": \"<string>\",\n \"unsubscribed\": true,\n \"attributes\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"jsmith@example.com\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"status_reason\": \"<string>\",\n \"unsubscribed\": true,\n \"attributes\": {}\n}"
response = http.request(request)
puts response.read_body{
"object": "contact",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"email": "jsmith@example.com",
"first_name": "<string>",
"last_name": "<string>",
"status": "enabled",
"status_reason": "<string>",
"unsubscribed": true,
"unsubscribed_at": "2023-11-07T05:31:56Z",
"attributes": {},
"validation_status": "unvalidated",
"last_validated_at": "2023-11-07T05:31:56Z"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}Update a Contact via the API
Change an AhaSend contact by ID or email address: its email, name, status, account-wide unsubscribe or attributes. Only the fields you send change.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/AhaSend/ahasend-go"
"github.com/AhaSend/ahasend-go/api"
"github.com/AhaSend/ahasend-go/models/requests"
"github.com/google/uuid"
)
func main() {
client := api.NewAPIClient(api.WithAPIKey(os.Getenv("AHASEND_API_KEY")))
accountID := uuid.MustParse(os.Getenv("AHASEND_ACCOUNT_ID"))
ctx := context.Background()
// Only the fields you set change. A nil attribute value deletes that key.
response, _, err := client.ContactsAPI.UpdateContact(ctx, accountID, "user+tag@example.com", requests.UpdateContactRequest{
FirstName: ahasend.String("Jordan"),
Attributes: map[string]any{"obsolete_key": nil},
})
if err != nil {
log.Fatalf("Error updating contact: %v", err)
}
fmt.Printf("Updated contact %s\n", response.ID)
}import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
const idOrEmail = "User+Tag@Example.COM";
const contact = await client.contacts.update(idOrEmail, {
unsubscribed: true,
attributes: { obsolete: null },
});
console.log("Contact updated.", { id: contact.id, unsubscribed: contact.unsubscribed });
curl --request PUT \
--url https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email": "jsmith@example.com",
"first_name": "<string>",
"last_name": "<string>",
"status_reason": "<string>",
"unsubscribed": true,
"attributes": {}
}
'import requests
url = "https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}"
payload = {
"email": "jsmith@example.com",
"first_name": "<string>",
"last_name": "<string>",
"status_reason": "<string>",
"unsubscribed": True,
"attributes": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'email' => 'jsmith@example.com',
'first_name' => '<string>',
'last_name' => '<string>',
'status_reason' => '<string>',
'unsubscribed' => true,
'attributes' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}HttpResponse<String> response = Unirest.put("https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"jsmith@example.com\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"status_reason\": \"<string>\",\n \"unsubscribed\": true,\n \"attributes\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ahasend.com/v2/accounts/{account_id}/contacts/{id_or_email}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"jsmith@example.com\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"status_reason\": \"<string>\",\n \"unsubscribed\": true,\n \"attributes\": {}\n}"
response = http.request(request)
puts response.read_body{
"object": "contact",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"email": "jsmith@example.com",
"first_name": "<string>",
"last_name": "<string>",
"status": "enabled",
"status_reason": "<string>",
"unsubscribed": true,
"unsubscribed_at": "2023-11-07T05:31:56Z",
"attributes": {},
"validation_status": "unvalidated",
"last_validated_at": "2023-11-07T05:31:56Z"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}contacts:write.
{id_or_email} is the contact ID or its email address. Percent-encode an email address exactly once. See Name a contact in the path.
Fields:
- A field that you leave out or send as
nulldoes not change. emailchanges the email address of the contact. An address that another contact of the account has is refused with409.attributesis merged into the stored attributes. Anullvalue removes that key. Other values must match the types that you defined in the dashboard. See Attributes.
unsubscribed: truestops campaigns to the contact on all lists. It does not change the contact’s memberships, and the contact no longer counts toward thecontact_countof any list. There is no operation that removes a contact from all lists.- To unsubscribe the contact from one list only, use Add or Update a List Contact with
subscription_status: "unsubscribed". - A change to
unsubscribeddoes not add or remove a suppression.
Related Guides
- API authentication, Permission scopes, Get Contact.
- Contacts API overview, API errors, API rate limits.
Authorizations
API key for authentication. Non-empty Security Requirement values are AhaSend API-key roles. Roles listed within one requirement object are jointly required; separate requirement objects are alternatives.
Path Parameters
Account ID
Contact UUID or email address. Percent-encode an email exactly once as a path segment; SDK callers pass the raw email value.
Body
A partial contact update. Omitted or null scalar fields and a null attributes object leave stored values unchanged. A present attributes object is merged; a null member removes that attribute key.
Response
Updated contact
Public contact projection. Attribute reads are legacy-safe: values can contain null, booleans, numbers, strings, arrays, or nested objects even though new writes accept only canonical dashboard-defined values.
Object type identifier
contact Unique identifier for the contact
When the contact was created
When the contact was last updated
Normalized contact email address
enabled, disabled, blocked Show child attributes
Show child attributes
unvalidated, valid, invalid, risky, unknown 
