package main
import (
"context"
"fmt"
"log"
"github.com/AhaSend/ahasend-go/api"
"github.com/AhaSend/ahasend-go/models/requests"
"github.com/google/uuid"
)
func main() {
// Create API client with authentication
client := api.NewAPIClient(
api.WithAPIKey("aha-sk-your-64-character-key"),
)
accountID := uuid.New()
// Create context for the API call
ctx := context.Background()
// Create a new API key
response, httpResp, err := client.APIKeysAPI.CreateAPIKey(
ctx,
accountID,
requests.CreateAPIKeyRequest{
Label: "My API Key",
Scopes: []string{
"messages:read:all",
"domains:read",
},
// Optional: restrict this key to specific source IPs (CIDR
// blocks or bare IPv4/IPv6 addresses). Omit or leave empty to
// allow the key to be used from any IP.
IPAllowList: []string{"203.0.113.0/24", "198.51.100.7"},
},
)
if err != nil {
log.Fatalf("Error creating API key: %v", err)
}
// Check response
if httpResp.StatusCode == 201 {
fmt.Printf("✅ Status: %d\n", httpResp.StatusCode)
// SecretKey is the one-time secret, returned ONLY on create.
if response != nil && response.SecretKey != nil {
// Store this value immediately — it cannot be retrieved again later.
fmt.Printf("Created API key, secret key: %s\n", *response.SecretKey)
}
} else {
fmt.Printf("❌ Unexpected status code: %d\n", httpResp.StatusCode)
}
}
import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
const apiKey = await client.apiKeys.create(
{ label: "Production API key", scopes: ["messages:send:all"] },
{ idempotencyKey: "sdk-sample-create-api-key" },
);
console.log("API key created.", { id: apiKey.id, label: apiKey.label });
curl --request POST \
--url https://api.ahasend.com/v2/accounts/{account_id}/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"label": "Production API Key",
"scopes": [
"messages:send:all",
"domains:read"
],
"ip_allow_list": [
"203.0.113.0/24",
"198.51.100.7"
]
}
'import requests
url = "https://api.ahasend.com/v2/accounts/{account_id}/api-keys"
payload = {
"label": "Production API Key",
"scopes": ["messages:send:all", "domains:read"],
"ip_allow_list": ["203.0.113.0/24", "198.51.100.7"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(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}/api-keys",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'label' => 'Production API Key',
'scopes' => [
'messages:send:all',
'domains:read'
],
'ip_allow_list' => [
'203.0.113.0/24',
'198.51.100.7'
]
]),
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.post("https://api.ahasend.com/v2/accounts/{account_id}/api-keys")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"label\": \"Production API Key\",\n \"scopes\": [\n \"messages:send:all\",\n \"domains:read\"\n ],\n \"ip_allow_list\": [\n \"203.0.113.0/24\",\n \"198.51.100.7\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ahasend.com/v2/accounts/{account_id}/api-keys")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"label\": \"Production API Key\",\n \"scopes\": [\n \"messages:send:all\",\n \"domains:read\"\n ],\n \"ip_allow_list\": [\n \"203.0.113.0/24\",\n \"198.51.100.7\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"object": "api_key",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"last_used_at": "2023-11-07T05:31:56Z",
"account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"label": "<string>",
"public_key": "<string>",
"scopes": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"api_key_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"scope": "<string>",
"domain_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"ip_allow_list": [
"<string>"
],
"secret_key": "<string>"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "A request with this idempotency key is already in progress"
}{
"message": "idempotency key was already used with a different request payload"
}{
"message": "Error message"
}Create API Key
Creates a new API key with the specified scopes
package main
import (
"context"
"fmt"
"log"
"github.com/AhaSend/ahasend-go/api"
"github.com/AhaSend/ahasend-go/models/requests"
"github.com/google/uuid"
)
func main() {
// Create API client with authentication
client := api.NewAPIClient(
api.WithAPIKey("aha-sk-your-64-character-key"),
)
accountID := uuid.New()
// Create context for the API call
ctx := context.Background()
// Create a new API key
response, httpResp, err := client.APIKeysAPI.CreateAPIKey(
ctx,
accountID,
requests.CreateAPIKeyRequest{
Label: "My API Key",
Scopes: []string{
"messages:read:all",
"domains:read",
},
// Optional: restrict this key to specific source IPs (CIDR
// blocks or bare IPv4/IPv6 addresses). Omit or leave empty to
// allow the key to be used from any IP.
IPAllowList: []string{"203.0.113.0/24", "198.51.100.7"},
},
)
if err != nil {
log.Fatalf("Error creating API key: %v", err)
}
// Check response
if httpResp.StatusCode == 201 {
fmt.Printf("✅ Status: %d\n", httpResp.StatusCode)
// SecretKey is the one-time secret, returned ONLY on create.
if response != nil && response.SecretKey != nil {
// Store this value immediately — it cannot be retrieved again later.
fmt.Printf("Created API key, secret key: %s\n", *response.SecretKey)
}
} else {
fmt.Printf("❌ Unexpected status code: %d\n", httpResp.StatusCode)
}
}
import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
const apiKey = await client.apiKeys.create(
{ label: "Production API key", scopes: ["messages:send:all"] },
{ idempotencyKey: "sdk-sample-create-api-key" },
);
console.log("API key created.", { id: apiKey.id, label: apiKey.label });
curl --request POST \
--url https://api.ahasend.com/v2/accounts/{account_id}/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"label": "Production API Key",
"scopes": [
"messages:send:all",
"domains:read"
],
"ip_allow_list": [
"203.0.113.0/24",
"198.51.100.7"
]
}
'import requests
url = "https://api.ahasend.com/v2/accounts/{account_id}/api-keys"
payload = {
"label": "Production API Key",
"scopes": ["messages:send:all", "domains:read"],
"ip_allow_list": ["203.0.113.0/24", "198.51.100.7"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(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}/api-keys",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'label' => 'Production API Key',
'scopes' => [
'messages:send:all',
'domains:read'
],
'ip_allow_list' => [
'203.0.113.0/24',
'198.51.100.7'
]
]),
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.post("https://api.ahasend.com/v2/accounts/{account_id}/api-keys")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"label\": \"Production API Key\",\n \"scopes\": [\n \"messages:send:all\",\n \"domains:read\"\n ],\n \"ip_allow_list\": [\n \"203.0.113.0/24\",\n \"198.51.100.7\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ahasend.com/v2/accounts/{account_id}/api-keys")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"label\": \"Production API Key\",\n \"scopes\": [\n \"messages:send:all\",\n \"domains:read\"\n ],\n \"ip_allow_list\": [\n \"203.0.113.0/24\",\n \"198.51.100.7\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"object": "api_key",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"last_used_at": "2023-11-07T05:31:56Z",
"account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"label": "<string>",
"public_key": "<string>",
"scopes": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"api_key_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"scope": "<string>",
"domain_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"ip_allow_list": [
"<string>"
],
"secret_key": "<string>"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "Error message"
}{
"message": "A request with this idempotency key is already in progress"
}{
"message": "idempotency key was already used with a different request payload"
}{
"message": "Error message"
}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.
Headers
Optional idempotency key for safe request retries. Must be a unique string for each logical request.
An identical request with a completed stored outcome returns the original status and body. An in-progress
execution returns 409, a changed method/path/body returns 422, and a released 5xx execution may run again.
Keys for non-secret responses expire after 24 hours. API-key create responses include a one-time secret_key,
so successful encrypted replay responses for those operations expire after 5 minutes.
255Path Parameters
Account ID
Body
Human-readable label for the API key; must not be empty
1 - 255Array of scope strings to grant to this API key
1Optional list of source IPs allowed to authenticate with this key. Each entry is a CIDR block (e.g. 203.0.113.0/24) or a bare IPv4/IPv6 address (stored as a /32 or /128). Entries are canonicalized (host bits are masked) and de-duplicated. The allow-all prefixes 0.0.0.0/0 and ::/0 are rejected, and at most 100 entries are allowed after de-duplication. Omit the field or pass an empty array to leave the key usable from any IP.
Response
API key created successfully
Object type identifier
api_key Unique identifier for the API key
When the API key was created
When the API key was last updated
When the API key was last used (updates every 5-10 minutes)
Account ID this API key belongs to
Human-readable label for the API key
Public portion of the API key
Scopes granted to this API key
Show child attributes
Show child attributes
Source IPs allowed to authenticate with this API key, as canonical CIDR blocks (a bare address is stored as a /32 for IPv4 or /128 for IPv6). Always present; an empty array means the key may be used from any source IP. When non-empty, an authenticated request whose client IP is not covered by an entry is rejected with HTTP 403 on every v2 endpoint, regardless of the key's scopes.
One-time secret key. Store it immediately. Exact successful idempotent replays return the same secret during the 5-minute encrypted replay window.

