MENU navbar-image

Introduction

This documentation aims to provide all the information you need to work with our API.

Signing in with two-factor authentication

Password sign-in is two steps when the account has two-factor authentication enabled.

This is rolled out per deployment. Until it is switched on, step 1 returns 200 {"token"} directly even for accounts with two-factor authentication, so clients should always send two_factor_supported: true and handle both 200 and 409.

  1. POST /api/v1/sanctum/token with email, password, device_name and two_factor_supported: true.
    • 200 {"token"}: no second factor is required. Done.
    • 409 {"two_factor_required": true, "challenge", "expires_in", "methods"}: continue to step 2.
  2. POST /api/v1/sanctum/token/two-factor with challenge, device_name, and either code (six digits from the authenticator app) or recovery_code.
    • 200 {"token"}: signed in.
    • 422 with attempts_remaining: wrong code, ask again.
    • 410: the challenge expired, was used, or was burned after five wrong codes. Go back to step 1.
    • 429 {"error": "two_factor_too_many_attempts", "retry_after"}: too many wrong codes across all challenges for this account (10 per 15 minutes). The challenge is burned; wait retry_after seconds, then start again at step 1.
    • 429 {"error": "two_factor_busy"}: another attempt for the same account is in progress; retry the same challenge shortly.
    • 429 with body {"message", "status": 429}: the per-challenge rate limit; wait a minute and retry the same challenge. If that then returns 410, start again at step 1.

A challenge is single-use and expires after five minutes. Each recovery code works once and is replaced. The numbers above (attempt caps, decay windows, TTLs) and the cutover date below are the current deployment's defaults and are configurable.

Clients that do not send two_factor_supported still receive a token for accounts with two-factor authentication until 2026-10-12, with a warnings entry of code two_factor_client_upgrade_required carrying the enforced_at date. From that date they receive 403 {"error": "two_factor_client_upgrade_required"}.

Google and Telegram sign-in are not challenged.

Anyone who knows the account's password can temporarily block API sign-in for that account by exhausting the per-account limit above; changing a leaked password is the remedy.

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your token by visiting your dashboard, find in menu API tokens and create a new one.

Endpoints

Create a token.

This endpoint lets you create a permanent token. When the account has two-factor authentication enabled and the client sends two_factor_supported: true, it returns 409 with a challenge to exchange at POST /api/v1/sanctum/token/two-factor.

Example request:
curl --request POST \
    "https://hidemail.app/api/v1/sanctum/token" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\",
    \"password\": \"password\",
    \"device_name\": \"Raycast\",
    \"two_factor_supported\": true
}"
const url = new URL(
    "https://hidemail.app/api/v1/sanctum/token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]",
    "password": "password",
    "device_name": "Raycast",
    "two_factor_supported": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/sanctum/token';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => '[email protected]',
            'password' => 'password',
            'device_name' => 'Raycast',
            'two_factor_supported' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/sanctum/token'
payload = {
    "email": "[email protected]",
    "password": "password",
    "device_name": "Raycast",
    "two_factor_supported": true
}
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200, Two-factor authentication off):


{
    "token": "1a2b3c..."
}
 

Example response (200, Legacy client during the grace window):


{
    "token": "1a2b3c...",
    "warnings": [
        {
            "code": "two_factor_client_upgrade_required",
            "message": "This app cannot ask for your two-factor authentication code. Update it before Oct 12, 2026, when signing in from this version will stop working.",
            "enforced_at": "2026-10-12"
        }
    ]
}
 

Example response (403, Legacy client after the cutover):


{
    "error": "two_factor_client_upgrade_required",
    "message": "Two-factor authentication is enabled on this account and this app cannot ask for your code. Update the app to sign in."
}
 

Example response (409, Two-factor challenge required):


{
    "two_factor_required": true,
    "challenge": "3f9c...64 chars",
    "expires_in": 300,
    "methods": [
        "totp",
        "recovery_code"
    ]
}
 

Example response (422, Wrong credentials):


{
    "message": "The provided credentials are incorrect.",
    "errors": {
        "email": [
            "The provided credentials are incorrect."
        ]
    }
}
 

Request      

POST api/v1/sanctum/token

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

email   string     

Email. Example: [email protected]

password   string     

Password. Example: password

device_name   string     

Device Name. Example: Raycast

two_factor_supported   boolean  optional    

Declares that the client can complete a two-factor challenge. Defaults to false. Example: true

Complete a two-factor challenge.

Exchanges the challenge returned by a 409 from POST /api/v1/sanctum/token for a permanent token. Send either a six-digit code from the authenticator app or one recovery_code. A challenge is single-use, expires after five minutes, and is burned after five wrong codes.

The two_factor_too_many_attempts 429 below burns the challenge, so the client must sign in with the password again to get a new one. This is distinct from the route's own rate limiter, whose 429 has a plain {"message", "status": 429} body (see App\Exceptions\Handler::handleApiException) and does not burn the challenge.

Example request:
curl --request POST \
    "https://hidemail.app/api/v1/sanctum/token/two-factor" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"challenge\": \"3f9c...\",
    \"device_name\": \"Raycast\",
    \"code\": \"123456\",
    \"recovery_code\": \"abcde12345-fghij67890\"
}"
const url = new URL(
    "https://hidemail.app/api/v1/sanctum/token/two-factor"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "challenge": "3f9c...",
    "device_name": "Raycast",
    "code": "123456",
    "recovery_code": "abcde12345-fghij67890"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/sanctum/token/two-factor';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'challenge' => '3f9c...',
            'device_name' => 'Raycast',
            'code' => '123456',
            'recovery_code' => 'abcde12345-fghij67890',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/sanctum/token/two-factor'
payload = {
    "challenge": "3f9c...",
    "device_name": "Raycast",
    "code": "123456",
    "recovery_code": "abcde12345-fghij67890"
}
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200, Verified):


{
    "token": "1a2b3c..."
}
 

Example response (410, Challenge unknown, expired or burned):


{
    "error": "two_factor_challenge_expired",
    "message": "This sign-in attempt has expired. Sign in with your password again."
}
 

Example response (422, Wrong code):


{
    "message": "The provided two factor authentication code was invalid.",
    "errors": {
        "code": [
            "The provided two factor authentication code was invalid."
        ]
    },
    "attempts_remaining": 3
}
 

Example response (429, Too many wrong codes for this account):


{
    "error": "two_factor_too_many_attempts",
    "message": "Too many incorrect codes. Try again later.",
    "retry_after": 900
}
 

Example response (429, Another request for this challenge or account is in flight):


{
    "error": "two_factor_busy",
    "message": "Another sign-in attempt is in progress. Try again in a moment."
}
 

Request      

POST api/v1/sanctum/token/two-factor

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

challenge   string     

The challenge from the 409 response. Example: 3f9c...

device_name   string     

Device Name. This is validated but not used to name the token: the device name recorded on the token is the one sent with the original POST /api/v1/sanctum/token request that issued this challenge. Example: Raycast

code   string  optional    

Six-digit authenticator code. Required unless recovery_code is present. Example: 123456

recovery_code   string  optional    

A recovery code. Required unless code is present. Example: abcde12345-fghij67890

GET api/user

requires authentication

Example request:
curl --request GET \
    --get "https://hidemail.app/api/user" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://hidemail.app/api/user"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/user';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/user'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Not authenticated"
}
 

Request      

GET api/user

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

POST api/v1/email/create

requires authentication

Example request:
curl --request POST \
    "https://hidemail.app/api/v1/email/create" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://hidemail.app/api/v1/email/create"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/email/create';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/email/create'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Not authenticated"
}
 

Request      

POST api/v1/email/create

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

GET api/v1/domain-options

requires authentication

Example request:
curl --request GET \
    --get "https://hidemail.app/api/v1/domain-options" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://hidemail.app/api/v1/domain-options"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/domain-options';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/domain-options'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Not authenticated"
}
 

Request      

GET api/v1/domain-options

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Create a new email alias.

requires authentication

This endpoint lets you create a new alias.

Example request:
curl --request POST \
    "https://hidemail.app/api/v1/aliases" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"description\": \"My new alias\"
}"
const url = new URL(
    "https://hidemail.app/api/v1/aliases"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "description": "My new alias"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/aliases';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'description' => 'My new alias',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/aliases'
payload = {
    "description": "My new alias"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "email": "[email protected]",
        "note": "My shopping account",
        "is_active": true,
        "created_at": "2024-01-28T15:03:09.000000Z",
        "updated_at": "2024-01-28T15:03:09.000000Z",
        "total_forwarded": 0,
        "total_blocked": 0
    }
}
 

Request      

POST api/v1/aliases

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

description   string  optional    

Note. Example: My new alias

Update an email alias note.

requires authentication

This endpoint allows you to update the note for a specific email alias.

Example request:
curl --request PATCH \
    "https://hidemail.app/api/v1/aliases" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"note\": \"My shopping account\",
    \"email\": \"[email protected]\"
}"
const url = new URL(
    "https://hidemail.app/api/v1/aliases"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "note": "My shopping account",
    "email": "[email protected]"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/aliases';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'note' => 'My shopping account',
            'email' => '[email protected]',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/aliases'
payload = {
    "note": "My shopping account",
    "email": "[email protected]"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PATCH', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "email": "[email protected]",
        "note": "My shopping account",
        "is_active": true,
        "created_at": "2024-01-28T15:03:09.000000Z",
        "updated_at": "2024-01-28T15:03:09.000000Z",
        "total_forwarded": 0,
        "total_blocked": 0
    }
}
 

Example response (404):


{
    "message": "Email alias not found"
}
 

Example response (422):


{
    "message": "The note field is required.",
    "errors": {
        "note": [
            "The note field is required."
        ]
    }
}
 

Request      

PATCH api/v1/aliases

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

note   string     

The new note for the alias. Max 255 characters. Must not be greater than 255 characters. Example: My shopping account

email   string     

The email alias to update. Must be a valid email address. Example: [email protected]

Get all aliases.

requires authentication

This endpoint lets you get all your aliases.

Example request:
curl --request GET \
    --get "https://hidemail.app/api/v1/aliases?page[number]=1&page[size]=100&search=shop&filter[is_active]=1&sort=-created_at" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://hidemail.app/api/v1/aliases"
);

const params = {
    "page[number]": "1",
    "page[size]": "100",
    "search": "shop",
    "filter[is_active]": "1",
    "sort": "-created_at",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/aliases';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page[number]' => '1',
            'page[size]' => '100',
            'search' => 'shop',
            'filter[is_active]' => '1',
            'sort' => '-created_at',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/aliases'
params = {
  'page[number]': '1',
  'page[size]': '100',
  'search': 'shop',
  'filter[is_active]': '1',
  'sort': '-created_at',
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "email": "[email protected]",
            "is_active": true,
            "note": null,
            "total_forwarded": 0,
            "total_blocked": 0,
            "created_at": "2026-10-08 20:26:19",
            "updated_at": "2026-10-08 20:26:19"
        },
        {
            "email": "[email protected]",
            "is_active": true,
            "note": null,
            "total_forwarded": 0,
            "total_blocked": 0,
            "created_at": "2026-10-08 20:26:19",
            "updated_at": "2026-10-08 20:26:19"
        }
    ]
}
 

Request      

GET api/v1/aliases

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

page   object  optional    

Pagination options.

page.number   integer  optional    

The page to return. Must be at least 1. Example: 1

page.size   integer  optional    

Aliases per page, up to 100. Must not be greater than 100. Must be at least 1. Example: 100

filter   object  optional    

Filters to apply.

search   string  optional    

Search aliases by email or note, 3 to 50 characters. Must not be greater than 50 characters. Must be at least 3 characters. Example: shop

filter.is_active   integer  optional    

Return only active (1) or inactive (0) aliases. Must not be greater than 1. Must be at least 0. Example: 1

sort   string  optional    

Sort field. Prefix with - for descending order. Must not be greater than 50 characters. Must be at least 3 characters. Example: -created_at

Must be one of:
  • email
  • is_active
  • created_at
  • updated_at
  • total_blocked
  • total_forwarded
  • -total_blocked
  • -total_forwarded
  • -email
  • -is_active
  • -created_at
  • -updated_at

Activate an alias.

requires authentication

This endpoint lets you update the status of an alias to active.

Example request:
curl --request POST \
    "https://hidemail.app/api/v1/active-aliases" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\"
}"
const url = new URL(
    "https://hidemail.app/api/v1/active-aliases"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/active-aliases';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => '[email protected]',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/active-aliases'
payload = {
    "email": "[email protected]"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "email": "[email protected]",
        "is_active": true,
        "note": null,
        "total_forwarded": 0,
        "total_blocked": 0,
        "created_at": "2026-10-08 20:26:19",
        "updated_at": "2026-10-08 20:26:19"
    }
}
 

Request      

POST api/v1/active-aliases

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

email   string     

The email you want to activate Example: [email protected]

Deactivate an alias.

requires authentication

This endpoint lets you update the status of an alias to in active.

Example request:
curl --request DELETE \
    "https://hidemail.app/api/v1/delete-aliases" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\"
}"
const url = new URL(
    "https://hidemail.app/api/v1/delete-aliases"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]"
};

fetch(url, {
    method: "DELETE",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/delete-aliases';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => '[email protected]',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/delete-aliases'
payload = {
    "email": "[email protected]"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "email": "[email protected]",
        "is_active": true,
        "note": null,
        "total_forwarded": 0,
        "total_blocked": 0,
        "created_at": "2026-10-08 20:26:19",
        "updated_at": "2026-10-08 20:26:19"
    }
}
 

Request      

DELETE api/v1/delete-aliases

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

email   string     

The email you want to deactivate Example: [email protected]

Set a webhook URL.

requires authentication

This endpoint lets you create a webhook URL. After you get email on any of your aliases we will send all data to this URL. You can do automation with this data and create your own integrations. The URL must use https, and the account owner is emailed whenever the webhook changes.

Example request:
curl --request POST \
    "https://hidemail.app/api/v1/subscribe" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"hookUrl\": \"https:\\/\\/hooks.slack.com\\/services\\/T0000\\/B0000\\/XXXXXXXX\"
}"
const url = new URL(
    "https://hidemail.app/api/v1/subscribe"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "hookUrl": "https:\/\/hooks.slack.com\/services\/T0000\/B0000\/XXXXXXXX"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/subscribe';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'hookUrl' => 'https://hooks.slack.com/services/T0000/B0000/XXXXXXXX',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/subscribe'
payload = {
    "hookUrl": "https:\/\/hooks.slack.com\/services\/T0000\/B0000\/XXXXXXXX"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Not authenticated"
}
 

Request      

POST api/v1/subscribe

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

hookUrl   string     

An https URL that receives a copy of every incoming email. Example: https://hooks.slack.com/services/T0000/B0000/XXXXXXXX

Remove a webhook URL.

requires authentication

This endpoint lets you remove a webhook URL. The account owner is emailed when a webhook is removed.

Example request:
curl --request DELETE \
    "https://hidemail.app/api/v1/unsubscribe" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://hidemail.app/api/v1/unsubscribe"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/unsubscribe';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/unsubscribe'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Not authenticated"
}
 

Request      

DELETE api/v1/unsubscribe

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Delete api token

requires authentication

This endpoint lets you remove an api token.

Example request:
curl --request DELETE \
    "https://hidemail.app/api/v1/delete-token" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://hidemail.app/api/v1/delete-token"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://hidemail.app/api/v1/delete-token';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://hidemail.app/api/v1/delete-token'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Not authenticated"
}
 

Request      

DELETE api/v1/delete-token

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json