Skip to main content
PUT
/
v2
/
accounts
/
{account_id}
/
sub-accounts
/
{sub_account_id}
/
api-keys
/
{key_id}
AhaSend Go SDK
package main

import (
  "context"
  "fmt"
  "log"

  "github.com/AhaSend/ahasend-go"
  "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()
  subAccountID := uuid.New()
  keyID := uuid.New()

  // Create context for the API call
  ctx := context.Background()

  // IPAllowList replaces the allowed source IPs; use &[]string{} to
  // clear it (any IP), or omit it to leave the current list unchanged.
  response, httpResp, err := client.SubAccountsAPI.UpdateSubAccountAPIKey(ctx, accountID, subAccountID, keyID, requests.UpdateAPIKeyRequest{Label: ahasend.String("Updated bootstrap key"), Scopes: &[]string{"messages:send:all", "domains:read"}, IPAllowList: &[]string{"203.0.113.0/24"}})
  if err != nil {
    log.Fatalf("Error updating sub-account API key: %v", err)
  }

  if httpResp.StatusCode == 200 {
    fmt.Printf("✅ Sub-account API key updated. Status: %d\n", httpResp.StatusCode)
    fmt.Printf("ID: %s\n", response.ID)
    fmt.Printf("Label: %s\n", response.Label)
    fmt.Printf("Scopes: %d\n", len(response.Scopes))
  } else {
    fmt.Printf("❌ Unexpected status code: %d\n", httpResp.StatusCode)
  }
}
{
  "object": "api_key",
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "created_at": "2023-11-07T05:31:56Z",
  "updated_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>"
  ],
  "last_used_at": "2023-11-07T05:31:56Z",
  "secret_key": "<string>"
}
Platform Partner feature: Sub Accounts is part of our Platform Partner capabilities and is currently in early access. Contact us to enable it on your account.

Authorizations

Authorization
string
header
required

API key for authentication

Path Parameters

account_id
string<uuid>
required

Parent account ID

sub_account_id
string<uuid>
required

Sub account ID

key_id
string<uuid>
required

API key ID

Body

application/json

At least one non-null field must be provided, and at least one provided value must differ from the current value. Omitted or null fields are left unchanged.

label
string
required

Human-readable label for the API key. Omit to keep the existing label.

Required string length: 1 - 255
scopes
string[] | null

Array of scope strings to grant to this API key

Minimum array length: 1
ip_allow_list
string[] | null

Replacement list of allowed source IPs (CIDR blocks or bare IPv4/IPv6 addresses; canonicalized and de-duplicated, at most 100 entries, allow-all prefixes 0.0.0.0/0 and ::/0 rejected). Omit the field or send null to leave the existing list unchanged; send an empty array to clear it (key usable from any IP); send a non-empty array to replace it.

Response

Sub-account API key updated successfully

object
enum<string>
required

Object type identifier

Available options:
api_key
id
string<uuid>
required

Unique identifier for the API key

created_at
string<date-time>
required

When the API key was created

updated_at
string<date-time>
required

When the API key was last updated

account_id
string<uuid>
required

Account ID this API key belongs to

label
string
required

Human-readable label for the API key

public_key
string
required

Public portion of the API key

scopes
object[]
required

Scopes granted to this API key

ip_allow_list
string[]
required

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.

last_used_at
string<date-time> | null

When the API key was last used (updates every 5-10 minutes)

secret_key
string

Secret key. Only returned when an API key is created, including exact idempotent replays of create requests within the 5-minute secret-bearing replay window. Store it immediately; list, get, update, and delete responses omit it.