MENU navbar-image

Introduction

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

Dates

Every date in a response is ISO 8601. A calendar day — a domain's expiry date, a subscription's commitment end date — is YYYY-MM-DD (2027-07-12). A moment in time — a contact's last update, a webhook's occurred_at — is YYYY-MM-DDTHH:MM:SSZ in UTC (2026-05-29T09:12:33Z).

The one exception is a value you hand back to us unchanged: the original of an M365 end date, and NextTermInstructions.CustomTermEndDate, stay in Microsoft's own /Date(...)/ notation, because that is what the ordering endpoints accept. The readable form of the same date sits next to it in formatted.

Webhooks

Instead of polling the API, you can register a webhook URL and receive a signed POST whenever a client, domain, product or Microsoft tenant changes. Configure it in the partner portal under Partner settings → Webhooks (URL, event types, a test button and a signing secret). Each delivery is signed with HMAC-SHA256 (X-Webhook-Signature); a 2xx response counts as delivered, failures are retried up to 10 times one hour apart. See the full Webhooks guide below for the payload format, signature verification, the resource/action list, retry policy and the source IP to allow-list.

Authenticating requests

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

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

You can retrieve access token by visiting Create Token

Authentication

Create Token

This method handles the creation of an OAuth token using the provided access token and credentials.

Example request:
curl --request POST \
    "https://api.nomeo.com/auth/token" \
    --header "Content-Type: application/json" \
    --data "{
    \"client_id\": \"01977c18-0fab-73bd-b8d1-7124b0186f0f\",
    \"client_secret\": \"secret123\",
    \"grant_type\": \"exercitationem\"
}"
const url = new URL(
    "https://api.nomeo.com/auth/token"
);

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

let body = {
    "client_id": "01977c18-0fab-73bd-b8d1-7124b0186f0f",
    "client_secret": "secret123",
    "grant_type": "exercitationem"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/auth/token';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'client_id' => '01977c18-0fab-73bd-b8d1-7124b0186f0f',
            'client_secret' => 'secret123',
            'grant_type' => 'exercitationem',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/auth/token'
payload = {
    "client_id": "01977c18-0fab-73bd-b8d1-7124b0186f0f",
    "client_secret": "secret123",
    "grant_type": "exercitationem"
}
headers = {
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "token_type": "Bearer",
    "expires_in": 31536000,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
    "refresh_token": "def5020009d130a2dcbe27f646d64e2610bc..."
}
 

Request   

POST auth/token

Headers

Content-Type        

Example: application/json

Body Parameters

client_id   string     

The OAuth client ID. Must match an existing stored value. Example: 01977c18-0fab-73bd-b8d1-7124b0186f0f

client_secret   string     

The OAuth client secret. Example: secret123

grant_type   string  optional    

Example: exercitationem

Refresh Token

This method handles the refreshing of an OAuth token using the provided refresh token.

Example request:
curl --request POST \
    "https://api.nomeo.com/auth/token/refresh" \
    --header "Content-Type: application/json" \
    --data "{
    \"refresh_token\": \"def50200a1b2c3d4...\",
    \"client_id\": \"01977c18-0fab-73bd-b8d1-7124b0186f0f\",
    \"client_secret\": \"secret123\"
}"
const url = new URL(
    "https://api.nomeo.com/auth/token/refresh"
);

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

let body = {
    "refresh_token": "def50200a1b2c3d4...",
    "client_id": "01977c18-0fab-73bd-b8d1-7124b0186f0f",
    "client_secret": "secret123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/auth/token/refresh';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'refresh_token' => 'def50200a1b2c3d4...',
            'client_id' => '01977c18-0fab-73bd-b8d1-7124b0186f0f',
            'client_secret' => 'secret123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/auth/token/refresh'
payload = {
    "refresh_token": "def50200a1b2c3d4...",
    "client_id": "01977c18-0fab-73bd-b8d1-7124b0186f0f",
    "client_secret": "secret123"
}
headers = {
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "token_type": "Bearer",
    "expires_in": 31536000,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
    "refresh_token": "def5020009d130a2dcbe27f646d64e2610bc..."
}
 

Request   

POST auth/token/refresh

Headers

Content-Type        

Example: application/json

Body Parameters

refresh_token   string     

The refresh token to obtain a new access token. Example: def50200a1b2c3d4...

client_id   string     

The OAuth client ID. Must match an existing stored value. Example: 01977c18-0fab-73bd-b8d1-7124b0186f0f

client_secret   string     

The OAuth client secret. Example: secret123

Clients

Clients APIs

Get list clients

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/clients?keyword=test" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/clients"
);

const params = {
    "keyword": "test",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/clients';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
        'query' => [
            'keyword' => 'test',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/clients'
params = {
  'keyword': 'test',
}
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "List clients",
    "data": [
        {
            "id": "1",
            "firstname": "Joe",
            "lastname": "Bin",
            "company": "",
            "address1": "Address 1",
            "address2": "",
            "city": "CT",
            "postcode": "8840",
            "country": "BE",
            "phone": "111111111",
            "email": "mail@domain.be",
            "client_type": "Managed Client",
            "vat_number": ""
        }
    ],
    "customData": []
}
 

Request   

GET clients

Headers

Authorization        

Example: Bearer {access token}

Query Parameters

keyword   string  optional    

Filter string on (part of) firstname, lastname, companyname. Example: test

Add client

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/clients/add" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"firstname\": \"Joe\",
    \"lastname\": \"Bin\",
    \"company\": \"Google\",
    \"password\": \"Pass!123\",
    \"postcode\": 1234,
    \"address1\": \"Address 1\",
    \"address2\": \"Address 2\",
    \"city\": \"Test\",
    \"country\": \"BE\",
    \"email\": \"info@domain.be\",
    \"phone\": 123456789,
    \"client_type\": \"Managed Client\",
    \"vat_number\": \"123456789\"
}"
const url = new URL(
    "https://api.nomeo.com/clients/add"
);

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

let body = {
    "firstname": "Joe",
    "lastname": "Bin",
    "company": "Google",
    "password": "Pass!123",
    "postcode": 1234,
    "address1": "Address 1",
    "address2": "Address 2",
    "city": "Test",
    "country": "BE",
    "email": "info@domain.be",
    "phone": 123456789,
    "client_type": "Managed Client",
    "vat_number": "123456789"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/clients/add';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'firstname' => 'Joe',
            'lastname' => 'Bin',
            'company' => 'Google',
            'password' => 'Pass!123',
            'postcode' => 1234.0,
            'address1' => 'Address 1',
            'address2' => 'Address 2',
            'city' => 'Test',
            'country' => 'BE',
            'email' => 'info@domain.be',
            'phone' => 123456789.0,
            'client_type' => 'Managed Client',
            'vat_number' => '123456789',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/clients/add'
payload = {
    "firstname": "Joe",
    "lastname": "Bin",
    "company": "Google",
    "password": "Pass!123",
    "postcode": 1234,
    "address1": "Address 1",
    "address2": "Address 2",
    "city": "Test",
    "country": "BE",
    "email": "info@domain.be",
    "phone": 123456789,
    "client_type": "Managed Client",
    "vat_number": "123456789"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Added Client",
    "data": [
        {
            "id": 11287,
            "firstname": "test",
            "lastname": "test2",
            "company": "MS",
            "address1": "test add 1",
            "address2": "",
            "city": "London",
            "postcode": "134",
            "country": "BE",
            "phone": "222222",
            "email": "testdomain7@test.be",
            "client_type": "Managed Client",
            "vat_number": "111"
        }
    ],
    "customData": []
}
 

Request   

POST clients/add

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

firstname   string     

First name, Number of chars between 1-100. Example: Joe

lastname   string     

Last name, Number of chars between 1-100. Example: Bin

company   string  optional    

Company name, Number of chars between 1-100. Example: Google

password   string     

Password, Number of chars between 6-100.
The password contains characters from at least three of the following five categories:
(1) English uppercase characters (A – Z)
(2) English lowercase characters (a – z)
(3) Base 10 digits (0 – 9)
(4) Non-alphanumeric (For example: !, $, #, or %)
(5) Unicode characters. Example: Pass!123

postcode   number     

Post code, must be entirely alpha-numeric characters. Number of chars between 1-100. Example: 1234

address1   string     

Address 1, Number of chars between 1-100. Example: Address 1

address2   string  optional    

Address 2, Number of chars between 1-100. Example: Address 2

city   string     

City name, Number of chars between 1-100. Example: Test

country   string     

2 characters ISO country code, Upper case, Reference: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes. Example: BE

email   string     

Email, Number of chars between 5-100. Example: info@domain.be

phone   number     

Phone, Number of chars between 5-25. Example: 123456789

client_type   string     

Client type.
Available options: "Managed Client", "Self Servicing Client". Example: Managed Client

vat_number   string  optional    

Vat number, must be entirely alpha-numeric characters. Number of chars between 3-100. Example: 123456789

Update client

requires authentication

Example request:
curl --request PUT \
    "https://api.nomeo.com/clients/1" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"firstname\": \"Joe\",
    \"lastname\": \"Bin\",
    \"company\": \"Google\",
    \"postcode\": 1234,
    \"address1\": \"Address 1\",
    \"address2\": \"Address 2\",
    \"city\": \"Test\",
    \"country\": \"BE\",
    \"email\": \"info@domain.be\",
    \"phone\": 123456789,
    \"vat_number\": \"123456789\"
}"
const url = new URL(
    "https://api.nomeo.com/clients/1"
);

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

let body = {
    "firstname": "Joe",
    "lastname": "Bin",
    "company": "Google",
    "postcode": 1234,
    "address1": "Address 1",
    "address2": "Address 2",
    "city": "Test",
    "country": "BE",
    "email": "info@domain.be",
    "phone": 123456789,
    "vat_number": "123456789"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/clients/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'firstname' => 'Joe',
            'lastname' => 'Bin',
            'company' => 'Google',
            'postcode' => 1234.0,
            'address1' => 'Address 1',
            'address2' => 'Address 2',
            'city' => 'Test',
            'country' => 'BE',
            'email' => 'info@domain.be',
            'phone' => 123456789.0,
            'vat_number' => '123456789',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/clients/1'
payload = {
    "firstname": "Joe",
    "lastname": "Bin",
    "company": "Google",
    "postcode": 1234,
    "address1": "Address 1",
    "address2": "Address 2",
    "city": "Test",
    "country": "BE",
    "email": "info@domain.be",
    "phone": 123456789,
    "vat_number": "123456789"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Updated Client",
    "data": [
        {
            "id": 11287,
            "firstname": "test",
            "lastname": "test2",
            "company": "MS",
            "address1": "test add 1",
            "address2": "",
            "city": "London",
            "postcode": "134",
            "country": "BE",
            "phone": "222222",
            "email": "testdomain7@test.be",
            "client_type": "Managed Client",
            "vat_number": "111"
        }
    ],
    "customData": []
}
 

Request   

PUT clients/{clientId}

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

clientId   string     

Client ID. Example: 1

Body Parameters

firstname   string     

First name, Number of chars between 1-100. Example: Joe

lastname   string     

Last name, Number of chars between 1-100. Example: Bin

company   string  optional    

Company name, Number of chars between 1-100. Example: Google

postcode   number     

Post code, must be entirely alpha-numeric characters. Number of chars between 1-100. Example: 1234

address1   string     

Address 1, Number of chars between 1-100. Example: Address 1

address2   string  optional    

Address 2, Number of chars between 1-100. Example: Address 2

city   string     

City name, Number of chars between 1-100. Example: Test

country   string     

2 characters ISO country code, Upper case, Reference: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes. Example: BE

email   string     

Email, Number of chars between 5-100. Example: info@domain.be

phone   number     

Phone, Number of chars between 5-25. Example: 123456789

vat_number   string  optional    

Vat number, must be entirely alpha-numeric characters. Number of chars between 3-100. Example: 123456789

Delete client

requires authentication

Example request:
curl --request DELETE \
    "https://api.nomeo.com/clients/1" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/clients/1"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/clients/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/clients/1'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Deleted Client"
}
 

Request   

DELETE clients/{clientId}

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

clientId   integer     

Client ID. Example: 1

Domain

Domain APIs

Register domain

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/domains/register" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"testdomain.com\",
    \"period\": 1,
    \"action\": \"register\",
    \"epp_code\": \"123456\",
    \"client_id\": 1,
    \"ns1\": \"ns1.com\",
    \"ns2\": \"ns2.com\",
    \"ns3\": \"ns3.com\",
    \"ns4\": \"ns4.com\"
}"
const url = new URL(
    "https://api.nomeo.com/domains/register"
);

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

let body = {
    "name": "testdomain.com",
    "period": 1,
    "action": "register",
    "epp_code": "123456",
    "client_id": 1,
    "ns1": "ns1.com",
    "ns2": "ns2.com",
    "ns3": "ns3.com",
    "ns4": "ns4.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/register';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'testdomain.com',
            'period' => 1,
            'action' => 'register',
            'epp_code' => '123456',
            'client_id' => 1,
            'ns1' => 'ns1.com',
            'ns2' => 'ns2.com',
            'ns3' => 'ns3.com',
            'ns4' => 'ns4.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/register'
payload = {
    "name": "testdomain.com",
    "period": 1,
    "action": "register",
    "epp_code": "123456",
    "client_id": 1,
    "ns1": "ns1.com",
    "ns2": "ns2.com",
    "ns3": "ns3.com",
    "ns4": "ns4.com"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (201):


{
    "success": true,
    "message": "Registered successfully",
    "data": {
        "order_id": 28883,
        "domain_id": "26024"
    },
    "customData": []
}
 

Request   

POST domains/register

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

name   string     

Domain name. Number of chars between 3-100. Example: testdomain.com

period   integer     

Number of years, between 1-10. Example: 1

action   string     

Domain action: "register" or "transfer". Example: register

epp_code   string  optional    

EPP transfer code. Number of chars between 3-100. Required when action=transfer. Example: 123456

client_id   integer  optional    

Client ID. You can get Client id in "Get list clients" API. Example: 1

ns1   string  optional    

Name Server 1, used only when action=transfer. A register, or a transfer without ns1-ns4, gets the default nameservers. Number of chars between 5-100. Example: ns1.com

ns2   string  optional    

Name Server 2, used only when action=transfer. Number of chars between 5-100. Example: ns2.com

ns3   string  optional    

Name Server 3, used only when action=transfer. Number of chars between 5-100. Example: ns3.com

ns4   string  optional    

Name Server 4, used only when action=transfer. Number of chars between 5-100. Example: ns4.com

Check the availability of domain

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/domains/check-domain" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"testdomain.com\"
}"
const url = new URL(
    "https://api.nomeo.com/domains/check-domain"
);

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

let body = {
    "name": "testdomain.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/check-domain';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'testdomain.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/check-domain'
payload = {
    "name": "testdomain.com"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "available": true,
    "message": "domaintest12345.com is available to register!"
}
 

Request   

POST domains/check-domain

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

name   string     

Domain name. Number of chars between 3-100. Example: testdomain.com

Get domains list

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/domains/list" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/list"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/list';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/list'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "data": [
        {
            "id": "123",
            "domain": "testdomain.be",
            "domain_name": "testdomain.be",
            "client_id": "123",
            "expire_date": "2020-12-08",
            "expired": true,
            "days_valid": 0,
            "status": "Pending",
            "cancelled_but_not_expired": false,
            "expiring_within_60_days": false,
            "expired_less_than_180_days_ago": false,
            "auto_renew": true,
            "registration_date": "2020-12-08",
            "registered_to": "2020-12-08",
            "registration_period": "1",
            "price": "123.00"
        }
    ]
}
 

Request   

GET domains/list

Headers

Authorization        

Example: Bearer {access token}

Get domain detail

requires authentication

auto_renew is false for a domain that will not renew on its own, which includes every cancelled or expired domain.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/domains/testdomain.com" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Domain",
    "data": {
        "id": "123",
        "domain": "testdomain.com",
        "domain_name": "testdomain.com",
        "client_id": "123",
        "expire_date": "2019-07-07",
        "expired": true,
        "days_valid": 0,
        "status": "Cancelled",
        "cancelled_but_not_expired": false,
        "expiring_within_60_days": false,
        "expired_less_than_180_days_ago": false,
        "auto_renew": false,
        "registration_date": "2015-07-07",
        "registered_to": "2019-07-07",
        "registration_period": "1",
        "price": "8.00",
        "contacts": {
            "registrant": {
                "id": 123,
                "first_name": "First name",
                "last_name": "Last name",
                "company_name": "Company",
                "vat": "123",
                "street": "Street 123",
                "number": "",
                "number_suffix": "",
                "city": "City 123",
                "state": "",
                "postal_code": "1234",
                "phone_number": "08495812451",
                "email_address": "test@gmail.com",
                "description": "",
                "timestamp_created": "2019-12-27T10:03:54Z",
                "timestamp_last_update": "2020-01-14T09:06:34Z",
                "is_verify_email": true,
                "email": "test@gmail.com",
                "country": "",
                "country_code": "BE",
                "handle": ""
            },
            "on_site": null,
            "tech": null,
            "admin": null
        },
        "nameservers": [
            {
                "handle": null,
                "name": "ns1.testdomain.com",
                "ipv4_address": null,
                "ipv6_address": null
            },
            {
                "handle": null,
                "name": "ns2.testdomain.com",
                "ipv4_address": null,
                "ipv6_address": null
            },
            {
                "handle": null,
                "name": "ns3.testdomain.com",
                "ipv4_address": null,
                "ipv6_address": null
            },
            {
                "handle": null,
                "name": "ns4.testdomain.com",
                "ipv4_address": null,
                "ipv6_address": null
            }
        ],
        "lock_status": "unlocked",
        "lock_supported": true,
        "dnssec": true,
        "dnssec_supported": true
    },
    "customData": []
}
 

Request   

GET domains/{domain}

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

domain   string     

Domain name. Number of chars between 3-100. Example: testdomain.com

Get domain DNS records

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/domains/testdomain.com/records" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/records"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/records';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/records'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "ResultCode": 200,
    "ResultMessage": "Here is zone 'testdomain.com'",
    "Success": true,
    "Result": {
        "Records": {
            "SOA": [
                {
                    "ChangeDate": 1675390325,
                    "Id": 123,
                    "Priority": 0,
                    "RecordData": "ns1.dns.be hostmaster.dns.be 2023020301 7200 7200 604800 3600",
                    "RecordMetaType": 0,
                    "RecordMetaTypeName": "Regular",
                    "RecordName": "testdomain.be",
                    "RecordType": 10,
                    "RecordTypeName": "SOA",
                    "TTL": 3600,
                    "ZoneId": 123
                }
            ],
            "A": [],
            "AAAA": [],
            "CNAME": [],
            "ANAME": [],
            "MX": [],
            "TXT": [],
            "SRV": [],
            "CAA": [],
            "NS": [],
            "DS": []
        },
        "Zone": {
            "Id": 123,
            "IsMaster": true,
            "IsSecure": false,
            "Master": null,
            "Name": "testdomain.be",
            "NotifiedSerial": "123",
            "NsType": "MASTER",
            "Nsec3Param": null,
            "Subdomains": []
        },
        "Office365HaveRecords": {
            "mx": {
                "mail": false
            },
            "cname": {
                "autodiscover": false,
                "sip": false,
                "lyncdiscover": false,
                "msoid": false,
                "enterpriseregistration": false,
                "enterpriseenrollment": false
            },
            "txt": {
                "spf": false
            },
            "srv": {
                "sip": false,
                "sipfederationtls": false
            }
        },
        "GoogleHaveRecords": {
            "mx": {
                "aspmx": false,
                "alt1": false,
                "alt2": false,
                "alt3": false,
                "alt4": false
            },
            "txt": {
                "spf": false
            }
        }
    }
}
 

Request   

GET domains/{domain}/records

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Create domain DNS record

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/domains/testdomain.com/record" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"record_type_name\": \"A\",
    \"record_name\": \"test.testdomain.com\",
    \"record_data\": \"1.2.3.4\",
    \"priority\": 1,
    \"fallback_ip\": \"1.2.3.4\"
}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/record"
);

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

let body = {
    "record_type_name": "A",
    "record_name": "test.testdomain.com",
    "record_data": "1.2.3.4",
    "priority": 1,
    "fallback_ip": "1.2.3.4"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/record';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'record_type_name' => 'A',
            'record_name' => 'test.testdomain.com',
            'record_data' => '1.2.3.4',
            'priority' => 1,
            'fallback_ip' => '1.2.3.4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/record'
payload = {
    "record_type_name": "A",
    "record_name": "test.testdomain.com",
    "record_data": "1.2.3.4",
    "priority": 1,
    "fallback_ip": "1.2.3.4"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "The record has been added to the zone!",
    "data": {
        "record_id": 123
    },
    "customData": []
}
 

Request   

POST domains/{domain}/record

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Body Parameters

record_type_name   string     

Record type name.
Avaiable options: SOA,A,AAAA,CNAME,ANAME,MX,TXT,SRV,CAA,NS,DS,LUA,ALIAS. Example: A

record_name   string     

Record name. Number of chars between 1-100. Example: test.testdomain.com

record_data   string     

Record data. Number of chars between 1-100. Example: 1.2.3.4

priority   integer     

Priority, between 1-1000. Example: 1

fallback_ip   string  optional    

Fallback IP if record_type_name=A. Example: 1.2.3.4

Update domain DNS record

requires authentication

Example request:
curl --request PUT \
    "https://api.nomeo.com/domains/testdomain.com/record" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"id\": \"1\",
    \"record_type_name\": \"A\",
    \"record_name\": \"test\",
    \"record_data\": \"1.2.3.4\",
    \"priority\": 1,
    \"fallback_ip\": \"1.2.3.4\"
}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/record"
);

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

let body = {
    "id": "1",
    "record_type_name": "A",
    "record_name": "test",
    "record_data": "1.2.3.4",
    "priority": 1,
    "fallback_ip": "1.2.3.4"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/record';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'id' => '1',
            'record_type_name' => 'A',
            'record_name' => 'test',
            'record_data' => '1.2.3.4',
            'priority' => 1,
            'fallback_ip' => '1.2.3.4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/record'
payload = {
    "id": "1",
    "record_type_name": "A",
    "record_name": "test",
    "record_data": "1.2.3.4",
    "priority": 1,
    "fallback_ip": "1.2.3.4"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "The record has been updated!",
    "data": [],
    "customData": []
}
 

Request   

PUT domains/{domain}/record

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Body Parameters

id   string     

Record ID. Example: 1

record_type_name   string     

Record type name.
Avaiable options: SOA,A,AAAA,CNAME,ANAME,MX,TXT,SRV,CAA,NS,DS,LUA. Example: A

record_name   string     

Record name. Number of chars between 1-100. Example: test

record_data   string     

Record data. Number of chars between 1-100. Example: 1.2.3.4

priority   integer     

Priority, between 1-1000. Example: 1

fallback_ip   string  optional    

Fallback IP if record_type_name=A. Example: 1.2.3.4

Delete domain DNS record

requires authentication

Example request:
curl --request DELETE \
    "https://api.nomeo.com/domains/testdomain.com/record/1" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/record/1"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/record/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/record/1'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "The record has been deleted!",
    "data": [],
    "customData": []
}
 

Request   

DELETE domains/{domain}/record/{recordId}

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

domain   string  optional    

Domain name. Example: testdomain.com

recordId   integer     

Record id. Example: 1

Change nameservers

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/domains/domain.com/change-nameservers" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ns_type\": \"our\",
    \"ns1\": \"ns1.example.com\",
    \"ns2\": \"ns2.example.com\",
    \"ns3\": \"ns3.example.com\",
    \"ns4\": \"ns4.example.com\",
    \"primary_ip\": \"192.168.1.1\"
}"
const url = new URL(
    "https://api.nomeo.com/domains/domain.com/change-nameservers"
);

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

let body = {
    "ns_type": "our",
    "ns1": "ns1.example.com",
    "ns2": "ns2.example.com",
    "ns3": "ns3.example.com",
    "ns4": "ns4.example.com",
    "primary_ip": "192.168.1.1"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/domain.com/change-nameservers';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ns_type' => 'our',
            'ns1' => 'ns1.example.com',
            'ns2' => 'ns2.example.com',
            'ns3' => 'ns3.example.com',
            'ns4' => 'ns4.example.com',
            'primary_ip' => '192.168.1.1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/domain.com/change-nameservers'
payload = {
    "ns_type": "our",
    "ns1": "ns1.example.com",
    "ns2": "ns2.example.com",
    "ns3": "ns3.example.com",
    "ns4": "ns4.example.com",
    "primary_ip": "192.168.1.1"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (201):


{
    "ResultCode": 1,
    "ResultMessage": "Updated domain nameservers!",
    "Success": true
}
 

Request   

POST domains/{domain}/change-nameservers

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

domain   string     

Domain name. Number of chars between 5-100. Example: domain.com

Body Parameters

ns_type   string  optional    

NS type: our, own, secondary. Default: our. Example: our

ns1   string  optional    

Name Server 1 (required if ns_type=own). Example: ns1.example.com

ns2   string  optional    

Name Server 2 (required if ns_type=own). Example: ns2.example.com

ns3   string  optional    

Name Server 3 (optional, only for ns_type=own). Example: ns3.example.com

ns4   string  optional    

Name Server 4 (optional, only for ns_type=own). Example: ns4.example.com

primary_ip   string  optional    

Primary IP (required if ns_type=secondary). Example: 192.168.1.1

Get domain lock

requires authentication

Whether the domain is locked against transfers. locked is null when the domain is not active or its extension does not support locking.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/domains/testdomain.com/lock" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/lock"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/lock';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/lock'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Domain lock",
    "data": {
        "locked": true
    },
    "customData": []
}
 

Example response (503):


{
    "success": false,
    "message": "The domain service is temporarily unavailable. Please try again later.",
    "data": [],
    "customData": []
}
 

Request   

GET domains/{domain}/lock

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Update domain lock

requires authentication

Locks or unlocks an active domain against transfers.

Example request:
curl --request PUT \
    "https://api.nomeo.com/domains/testdomain.com/lock" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"locked\": true
}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/lock"
);

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

let body = {
    "locked": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/lock';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'locked' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/lock'
payload = {
    "locked": true
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Domain locked",
    "data": {
        "locked": true
    },
    "customData": []
}
 

Example response (422):


{
    "success": false,
    "message": "The extension of this domain does not support locking.",
    "data": [],
    "customData": []
}
 

Request   

PUT domains/{domain}/lock

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Body Parameters

locked   boolean     

true to lock the domain, false to unlock it. Example: true

Get domain auto-renew

requires authentication

Whether the domain will renew on its own. A cancelled or expired domain never does, whatever its renewal setting.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/domains/testdomain.com/autorenew" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/autorenew"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/autorenew';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/autorenew'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Domain auto-renew",
    "data": {
        "auto_renew": true
    },
    "customData": []
}
 

Request   

GET domains/{domain}/autorenew

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Update domain auto-renew

requires authentication

Switches the automatic renewal of an active domain on or off.

Example request:
curl --request PUT \
    "https://api.nomeo.com/domains/testdomain.com/autorenew" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"auto_renew\": false
}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/autorenew"
);

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

let body = {
    "auto_renew": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/autorenew';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'auto_renew' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/autorenew'
payload = {
    "auto_renew": false
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Domain auto-renew updated.",
    "data": {
        "auto_renew": false
    },
    "customData": []
}
 

Request   

PUT domains/{domain}/autorenew

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Body Parameters

auto_renew   boolean     

true to renew the domain automatically, false to let it expire. Example: false

Get domain DNSSEC

requires authentication

Whether the domain is secured with DNSSEC. dnssec is null when the domain is not active or its extension does not support DNSSEC (see dnssec_supported in "Get domain detail"). update_pending is true while a DNSSEC change is still being processed by the registry; until then dnssec shows the previous state.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/domains/testdomain.com/dnssec" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/dnssec"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/dnssec';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/dnssec'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Domain DNSSEC",
    "data": {
        "dnssec": true,
        "update_pending": false
    },
    "customData": []
}
 

Example response (503):


{
    "success": false,
    "message": "The domain service is temporarily unavailable. Please try again later.",
    "data": [],
    "customData": []
}
 

Request   

GET domains/{domain}/dnssec

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Update domain DNSSEC

requires authentication

Switches DNSSEC on or off for an active domain. It can only be switched on for a domain that uses our nameservers: on other nameservers the DNS provider signs the zone, and its keys have to be added at the registry.

Example request:
curl --request PUT \
    "https://api.nomeo.com/domains/testdomain.com/dnssec" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"dnssec\": true
}"
const url = new URL(
    "https://api.nomeo.com/domains/testdomain.com/dnssec"
);

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

let body = {
    "dnssec": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/domains/testdomain.com/dnssec';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'dnssec' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/domains/testdomain.com/dnssec'
payload = {
    "dnssec": true
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Zone secured",
    "data": {
        "dnssec": true
    },
    "customData": []
}
 

Example response (422):


{
    "success": false,
    "message": "DNSSEC can only be switched on for a domain that uses our nameservers.",
    "data": [],
    "customData": []
}
 

Request   

PUT domains/{domain}/dnssec

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

domain   string     

Domain name. Example: testdomain.com

Body Parameters

dnssec   boolean     

true to secure the domain, false to remove DNSSEC. Example: true

Endpoints

Ingestion endpoint — receives a normalized event pushed from the `api` repo and fans it out to every enabled webhook of the partner that subscribes to the resource type.

requires authentication

POST /admin/webhook-events

Example request:
curl --request POST \
    "https://api.nomeo.com/admin/webhook-events" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"partner_id\": \"qui\",
    \"event_id\": \"explicabo\",
    \"occurred_at\": \"et\",
    \"resource_type\": \"ut\",
    \"resource_id\": \"suscipit\",
    \"action\": \"vero\"
}"
const url = new URL(
    "https://api.nomeo.com/admin/webhook-events"
);

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

let body = {
    "partner_id": "qui",
    "event_id": "explicabo",
    "occurred_at": "et",
    "resource_type": "ut",
    "resource_id": "suscipit",
    "action": "vero"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/webhook-events';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'partner_id' => 'qui',
            'event_id' => 'explicabo',
            'occurred_at' => 'et',
            'resource_type' => 'ut',
            'resource_id' => 'suscipit',
            'action' => 'vero',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/webhook-events'
payload = {
    "partner_id": "qui",
    "event_id": "explicabo",
    "occurred_at": "et",
    "resource_type": "ut",
    "resource_id": "suscipit",
    "action": "vero"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Request   

POST admin/webhook-events

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

partner_id   string     

Example: qui

event_id   string     

Example: explicabo

occurred_at   string     

Example: et

resource_type   string     

Example: ut

resource_id   string     

Example: suscipit

action   string     

Example: vero

GET /admin/partners/{partnerId}/webhooks

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/admin/partners/illum/webhooks" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/illum/webhooks"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/illum/webhooks';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/illum/webhooks'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (401):

Show headers
cache-control: no-cache, private
x-ratelimit-limit: 60
x-ratelimit-remaining: 59
content-type: text/html; charset=utf-8
 

Unauthorized.
 

Request   

GET admin/partners/{partnerId}/webhooks

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

partnerId   string     

Example: illum

POST /admin/partners/{partnerId}/webhooks Creates a webhook and returns its secret once.

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/admin/partners/voluptas/webhooks" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/voluptas/webhooks"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/voluptas/webhooks';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/voluptas/webhooks'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Request   

POST admin/partners/{partnerId}/webhooks

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

partnerId   string     

Example: voluptas

POST /admin/partners/{partnerId}/webhooks/test Sends a sample event to the given url (works before a webhook exists).

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/admin/partners/aut/webhooks/test" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"url\": \"http:\\/\\/zieme.com\\/facere-qui-cupiditate-sed-atque-commodi-aut\"
}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/aut/webhooks/test"
);

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

let body = {
    "url": "http:\/\/zieme.com\/facere-qui-cupiditate-sed-atque-commodi-aut"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/aut/webhooks/test';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'url' => 'http://zieme.com/facere-qui-cupiditate-sed-atque-commodi-aut',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/aut/webhooks/test'
payload = {
    "url": "http:\/\/zieme.com\/facere-qui-cupiditate-sed-atque-commodi-aut"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Request   

POST admin/partners/{partnerId}/webhooks/test

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

partnerId   string     

Example: aut

Body Parameters

url   string     

Must be a valid URL. Must start with one of https:// Must not be greater than 2048 characters. Example: http://zieme.com/facere-qui-cupiditate-sed-atque-commodi-aut

webhook_id   string  optional    

PUT /admin/partners/{partnerId}/webhooks/{webhookId}

requires authentication

Example request:
curl --request PUT \
    "https://api.nomeo.com/admin/partners/porro/webhooks/qui" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/porro/webhooks/qui"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/porro/webhooks/qui';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/porro/webhooks/qui'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Request   

PUT admin/partners/{partnerId}/webhooks/{webhookId}

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

partnerId   string     

Example: porro

webhookId   string     

Example: qui

DELETE /admin/partners/{partnerId}/webhooks/{webhookId}

requires authentication

Example request:
curl --request DELETE \
    "https://api.nomeo.com/admin/partners/dolor/webhooks/et" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/dolor/webhooks/et"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/dolor/webhooks/et';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/dolor/webhooks/et'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Request   

DELETE admin/partners/{partnerId}/webhooks/{webhookId}

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

partnerId   string     

Example: dolor

webhookId   string     

Example: et

POST /admin/partners/{partnerId}/webhooks/{webhookId}/secret/rotate

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/admin/partners/architecto/webhooks/reprehenderit/secret/rotate" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/architecto/webhooks/reprehenderit/secret/rotate"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/architecto/webhooks/reprehenderit/secret/rotate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/architecto/webhooks/reprehenderit/secret/rotate'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Request   

POST admin/partners/{partnerId}/webhooks/{webhookId}/secret/rotate

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

partnerId   string     

Example: architecto

webhookId   string     

Example: reprehenderit

GET /admin/partners/{partnerId}/webhooks/{webhookId}/logs Last 100 delivery attempts for a single webhook.

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/admin/partners/accusamus/webhooks/maxime/logs" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/admin/partners/accusamus/webhooks/maxime/logs"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/admin/partners/accusamus/webhooks/maxime/logs';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/admin/partners/accusamus/webhooks/maxime/logs'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (401):

Show headers
cache-control: no-cache, private
x-ratelimit-limit: 60
x-ratelimit-remaining: 59
content-type: text/html; charset=utf-8
 

Unauthorized.
 

Request   

GET admin/partners/{partnerId}/webhooks/{webhookId}/logs

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

partnerId   string     

Example: accusamus

webhookId   string     

Example: maxime

Products

Products APIs

Get list of Partner's Services

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/services?client_id=1" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/services"
);

const params = {
    "client_id": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/services';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
        'query' => [
            'client_id' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/services'
params = {
  'client_id': '1',
}
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "data": [
        {
            "id": "123",
            "pid": "123",
            "client_id": "123",
            "name": "Microsoft 365 - NCE",
            "next_due_date": "2022-07-01",
            "domain": "test.onmicrosoft.com",
            "status": "Active",
            "billing_cycle": "Monthly",
            "reg_date": "2022-07-01",
            "first_payment_amount": "0.00",
            "recurring_amount": "0.00",
            "days_remain": -229,
            "login": "",
            "password": "",
            "reg_number": "",
            "number_of_users": "",
            "gdata_valid_until": "2023-07-01",
            "platform": ""
        }
    ]
}
 

Request   

GET products/services

Headers

Authorization        

Example: Bearer {access token}

Query Parameters

client_id   integer  optional    

Filter by Client ID. Example: 1

Get list of Partner's Licenses

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/licenses" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/licenses"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/licenses';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/licenses'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "licenses": [
        {
            "id": "123",
            "pid": "123",
            "client_id": "123",
            "name": "Gdata Internet Security",
            "next_due_date": "2021-09-14",
            "domain": "test",
            "status": "Active",
            "billing_cycle": "One Time",
            "reg_date": "2021-09-14",
            "first_payment_amount": "114.97",
            "recurring_amount": "181.78",
            "days_remain": -519,
            "login": "",
            "password": "",
            "reg_number": "",
            "number_of_users": "",
            "gdata_valid_until": "2022-09-14",
            "platform": ""
        }
    ],
    "expiringWithin60days": 0
}
 

Request   

GET products/licenses

Headers

Authorization        

Example: Bearer {access token}

Get Subscription Catalog

requires authentication

Important Notes: This api will return all subscription catalog, with "Terms". You can use this term information to use correct term duration and billing circle value when use "Add a new M365 subscription" API.

Example: "Terms": ["P1M:P1M","P1Y:P1Y","P1Y:P1M"] => List of available term duration & billing circle for this Catalog. When user choose "P1M" term duration, they can choose "P1M" billing circle only. When user choose "P1Y" term duration, they can choose "P1Y" or "P1M" billing circle.

Display value for user: P1M: Monthly, P1Y: Annually, P3Y: Triennially, P1X: One-Time

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/m365/catalog" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/m365/catalog"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/m365/catalog';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/m365/catalog'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Subscription Catalog",
    "data": [
        {
            "Title": "Azure Active Directory Premium P1",
            "Description": "Azure Active Directory Premium provides single sign-on to thousands of cloud (SaaS) apps and access to web apps you run on-premises. Built for ease of use, Azure Active Directory Premium features multi-factor authentication (MFA); access control based on device health, user location, and identity; and holistic security reports, audits, and alerts.\r\nAzure Active Directory Premium provides single sign-on to thousands of cloud (SaaS) apps and access to web apps you run on-premises. Built for ease of use, Azure Active Directory Premium features multi-factor authentication (MFA); access control based on device health, user location, and identity; and holistic security reports, audits, and alerts.",
            "Terms": [
                "P1M:P1M",
                "P1Y:P1Y",
                "P1Y:P1M"
            ],
            "Id": "75",
            "ProductSKU": "SKUNUMBER"
        }
    ]
}
 

Request   

GET products/m365/catalog

Headers

Authorization        

Example: Bearer {access token}

Add Tenant

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/products/m365/tenant" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"tenant_name\": \"testtenant\",
    \"client_id\": 1
}"
const url = new URL(
    "https://api.nomeo.com/products/m365/tenant"
);

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

let body = {
    "tenant_name": "testtenant",
    "client_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/m365/tenant';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'tenant_name' => 'testtenant',
            'client_id' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/m365/tenant'
payload = {
    "tenant_name": "testtenant",
    "client_id": 1
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (201):


{
    "success": true,
    "message": "Added Tenant",
    "data": {
        "service_id": "18868"
    },
    "customData": []
}
 

Request   

POST products/m365/tenant

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

tenant_name   string     

Tenant name without .onmicrosoft.com. Number of chars between 1-100, must be entirely alpha-numeric characters. Example: testtenant

client_id   integer  optional    

Client ID. You can get Client id in "Get list clients" API. Example: 1

Add an existing tenant

requires authentication

Adds a Microsoft 365 tenant that exists already, created with Microsoft or another provider, to one of your clients so licenses can be ordered for it. Give one of the tenant's domains: its .onmicrosoft.com domain or a custom domain verified in the tenant. A name without a dot is taken as "<name>.onmicrosoft.com".

The tenant has to accept a reseller relationship with us first. Until it has, the call answers with "invitation_url": the tenant's global admin opens it and accepts the relationship, after which this call can be repeated.
When the client has this tenant already, nothing is ordered and the existing "service_id" is returned with "already_added".

By adding the tenant you confirm that the client accepted the Microsoft Customer Agreement and our terms for NCE subscriptions. Checking the reseller relationship reads the tenant at Microsoft: allow this call up to a minute.

Example request:
curl --request POST \
    "https://api.nomeo.com/products/m365/tenant/existing" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"tenant_name\": \"contoso.onmicrosoft.com\",
    \"client_id\": 1
}"
const url = new URL(
    "https://api.nomeo.com/products/m365/tenant/existing"
);

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

let body = {
    "tenant_name": "contoso.onmicrosoft.com",
    "client_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/m365/tenant/existing';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'tenant_name' => 'contoso.onmicrosoft.com',
            'client_id' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/m365/tenant/existing'
payload = {
    "tenant_name": "contoso.onmicrosoft.com",
    "client_id": 1
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Added existing tenant",
    "data": {
        "service_id": "123",
        "tenant_id": "fe1403d5-0000-0000-0000-7cded881c91d",
        "already_added": false
    },
    "customData": []
}
 

Example response (200, The client has this tenant already):


{
    "success": true,
    "message": "This tenant was added for this client already",
    "data": {
        "service_id": "123",
        "tenant_id": "fe1403d5-0000-0000-0000-7cded881c91d",
        "already_added": true
    },
    "customData": []
}
 

Example response (200, No reseller relationship yet):


{
    "success": false,
    "message": "contoso.onmicrosoft.com has no reseller relationship with us yet",
    "data": {
        "tenant_name": "contoso.onmicrosoft.com",
        "tenant_id": "fe1403d5-0000-0000-0000-7cded881c91d",
        "invitation_url": "https://admin.microsoft.com/Adminportal/Home?invType=ResellerRelationship&partnerId=649c51c4-430a-4f59-b1a7-f7c104d0189f&msppId=0#/partners/invitation"
    },
    "customData": []
}
 

Request   

POST products/m365/tenant/existing

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

tenant_name   string     

Domain of the tenant. Example: contoso.onmicrosoft.com

client_id   integer     

Client ID. You can get Client id in "Get list of Partner's Clients" API. Example: 1

Check the availability of the Microsoft tenant name

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/m365/check-tenant" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"tenant_name\": \"testtenant\"
}"
const url = new URL(
    "https://api.nomeo.com/products/m365/check-tenant"
);

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

let body = {
    "tenant_name": "testtenant"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/m365/check-tenant';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'tenant_name' => 'testtenant',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/m365/check-tenant'
payload = {
    "tenant_name": "testtenant"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (201):


{
    "success": true,
    "available": true,
    "message": "test.onmicrosoft.com is available to register!"
}
 

Request   

GET products/m365/check-tenant

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

Body Parameters

tenant_name   string     

Tenant name without .onmicrosoft.com. Number of chars between 1-100, must be entirely alpha-numeric characters. Example: testtenant

Search tenant id

requires authentication

Looks up the id of an existing Microsoft 365 tenant from one of its domains: its .onmicrosoft.com domain, or a custom domain verified in the tenant. A name without a dot is taken as "<name>.onmicrosoft.com".

Finding a tenant does not mean it can be added yet: that also takes a reseller relationship between the tenant and us.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/m365/search-tenant?tenant_name=contoso.onmicrosoft.com" \
    --header "Authorization: Bearer {access token}" \
const url = new URL(
    "https://api.nomeo.com/products/m365/search-tenant"
);

const params = {
    "tenant_name": "contoso.onmicrosoft.com",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/m365/search-tenant';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
        'query' => [
            'tenant_name' => 'contoso.onmicrosoft.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/m365/search-tenant'
params = {
  'tenant_name': 'contoso.onmicrosoft.com',
}
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "",
    "data": {
        "tenant_name": "contoso.onmicrosoft.com",
        "tenant_id": "fe1403d5-0000-0000-0000-7cded881c91d"
    },
    "customData": []
}
 

Example response (200, No tenant has this domain):


{
    "success": false,
    "message": "No tenant found for contoso.onmicrosoft.com",
    "data": {
        "tenant_name": "contoso.onmicrosoft.com",
        "tenant_id": null
    },
    "customData": []
}
 

Request   

GET products/m365/search-tenant

Headers

Authorization        

Example: Bearer {access token}

Query Parameters

tenant_name   string     

Domain of the tenant. Example: contoso.onmicrosoft.com

Body Parameters

tenant_name   string  optional    

Add a new M365 subscription

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscription" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"quantity\": 1,
    \"term_duration\": \"P1M\",
    \"billing_cycle\": \"P1M\",
    \"catalog_id\": 77
}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription"
);

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

let body = {
    "quantity": 1,
    "term_duration": "P1M",
    "billing_cycle": "P1M",
    "catalog_id": 77
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'quantity' => 1,
            'term_duration' => 'P1M',
            'billing_cycle' => 'P1M',
            'catalog_id' => 77,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription'
payload = {
    "quantity": 1,
    "term_duration": "P1M",
    "billing_cycle": "P1M",
    "catalog_id": 77
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "data": {
        "TenantId": "x-x-x-x-x",
        "ErpOrderId": "123",
        "IsAddonOrder": false,
        "Subscriptions": [
            {
                "AutoRenewEnabled": true,
                "BillingCycle": "P1M",
                "CustomTermEndDate": null,
                "ErpOrderId": null,
                "FriendlyName": "Azure Active Directory Premium P1",
                "OfferId": "CFQ7TTC0LH16:0001",
                "OrderId": null,
                "PartnerId": "123",
                "ProductId": "77",
                "Quantity": 1,
                "SkuId": null,
                "Status": 1,
                "SubscriptionId": "",
                "TenantId": "x-x-x-x-x",
                "TermDuration": "P1M",
                "WhmcsServiceId": null
            }
        ]
    }
}
 

Request   

POST products/{serviceId}/m365/subscription

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Body Parameters

quantity   integer     

Quantity, Must between 1-100. Example: 1

term_duration   string     

Term Duration.
Available options: P1M,P1Y,P3Y,P1X.
Please read this document to get value: "Get Subscription Catalog" A PI. Example: P1M

billing_cycle   string     

Billing Duration.
Available options: P1M,P1Y,P3Y,P1X.
Please read this document to get value: "Get Subscription Catalog" API. Example: P1M

catalog_id   integer     

Subscription Catalog Id. You can get Subscription Catalog Id in "Get Subscription Catalog" API. Example: 77

Update M365 subscription quantity

requires authentication

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/update/quantity" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"quantity\": 1
}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/update/quantity"
);

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

let body = {
    "quantity": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/update/quantity';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'quantity' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/update/quantity'
payload = {
    "quantity": 1
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Subscription has been updated!",
    "data": {
        "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d",
        "ErpOrderId": "1000",
        "IsAddonOrder": false,
        "Subscriptions": [
            {
                "AutoRenewEnabled": true,
                "BillingCycle": "Monthly",
                "CustomTermEndDate": null,
                "ErpOrderId": null,
                "FriendlyName": "Microsoft 365 Business Standard",
                "OfferId": "CFQ7TTC0LDPB:0001",
                "OrderId": "000000000000",
                "PartnerId": "1000000",
                "ProductId": null,
                "Quantity": 1,
                "SkuId": null,
                "Status": 0,
                "SubscriptionId": "90f37eae-0000-0000-0000-1ee0fa9ffdb9",
                "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d",
                "TermDuration": "P1Y",
                "WhmcsServiceId": null
            }
        ]
    },
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/subscription/{subscriptionId}/update/quantity

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

subscriptionId   string     

Subscription ID. Example: 9cb50556-0000-40000-0000-3fdcc63ad0fd

Body Parameters

quantity   integer     

Quantity, Must between 1-10000. Example: 1

Get list of User's M365 subscriptions

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/1/m365/subscriptions" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscriptions"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscriptions';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscriptions'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "nce_licenses": [
        {
            "AutoRenewEnabled": false,
            "ProductId": 1,
            "AvailableUnits": 2,
            "BillingCycle": "Monthly",
            "CancellationAllowedUntilDate": "2023-01-29",
            "CatalogItemId": "ABC:0001:123",
            "CommitmentEndDate": "2023-02-21",
            "ConsumedUnits": 0,
            "CreationDate": "2022-12-22",
            "EffectiveStartDate": "2022-12-22",
            "FriendlyName": "Exchange Online (Plan 1)",
            "IsNewCommerceExperienceSubscription": true,
            "MinimumQuantity": 2,
            "NextTermInstructions": null,
            "OfferId": "ABC:0001",
            "OrderId": "123abc",
            "ParentSubscriptionId": null,
            "PartnerId": "123",
            "ProductSku": "CFQ7TTC0LH16:0001",
            "PromotionId": null,
            "SkuPartNumber": "UNKNOWN",
            "Status": 0,
            "SubscriptionId": "378dc3d8-1234-1234-1234-eed13edbeacd",
            "SubscriptionQuantity": 2,
            "TenantId": "5f5e68d7-1234-1234-1234-a5ea6972ddb5",
            "TermDuration": "P1M",
            "TotalUnits": 2,
            "IsAddon": false,
            "AllowCancel": false,
            "MinQuantity": 2,
            "RecentTransactions": [],
            "microsoft_standard_end_user_price": null,
            "reseller_end_user_price": null,
            "actual_sale_price": null,
            "user_price": null,
            "user_item_price": null,
            "end_dates_sort": [
                {
                    "original": "/Date(1708487255000)/",
                    "formatted": "2024-02-21"
                }
            ]
        }
    ]
}
 

Request   

GET products/{serviceId}/m365/subscriptions

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Refresh User's M365 subscriptions

requires authentication

Reads the subscriptions of the tenant from Microsoft again, stores them and returns them. The response is the same as "Get list of User's M365 subscriptions", plus the outcome of the refresh.

The subscriptions are always returned. When "refreshed" is true they were just read from Microsoft, at "refreshed_at". When it is false, "reason" says why and the stored subscriptions are returned:
- throttled: the tenant was refreshed less than a minute ago, "retry_after" gives the seconds to wait
- sync_in_progress: the tenant is being synchronised already, try again shortly
- upstream_unavailable: Microsoft could not be reached
- sync_failed: the subscriptions were read but could not be stored
- tenant_not_found: there is no M365 tenant for this service

Reading a tenant at Microsoft takes a while: allow this call up to two minutes.

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscriptions/refresh" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscriptions/refresh"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscriptions/refresh';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscriptions/refresh'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "nce_licenses": [
        {
            "AutoRenewEnabled": false,
            "BillingCycle": "Monthly",
            "CancellationAllowedUntilDate": "2026-10-07",
            "CommitmentEndDate": "2026-10-30",
            "FriendlyName": "Exchange Online (Plan 1)",
            "OfferId": "CFQ7TTC0LH16:0001",
            "Status": 0,
            "SubscriptionId": "9cb50556-0000-40000-0000-3fdcc63ad0fd",
            "SubscriptionQuantity": 1,
            "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d",
            "TermDuration": "P1M"
        }
    ],
    "refreshed": true,
    "refreshed_at": "2026-09-30T09:12:44+02:00",
    "reason": null
}
 

Example response (200, Refreshed less than a minute ago):


{
    "nce_licenses": [],
    "refreshed": false,
    "refreshed_at": null,
    "reason": "throttled",
    "retry_after": 42
}
 

Request   

POST products/{serviceId}/m365/subscriptions/refresh

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Get possible end dates for coterminous M365 subscriptions

requires authentication

Returns the commitment end dates of the active yearly subscriptions of the tenant, plus one year after the earliest one. A new subscription ordered with one of these end dates ends together with the existing subscriptions.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/1/m365/subscriptions/end-dates" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscriptions/end-dates"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscriptions/end-dates';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscriptions/end-dates'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "",
    "data": [
        {
            "original": "/Date(1708487255000)/",
            "formatted": "2024-02-21"
        },
        {
            "original": "/Date(1740023255000)/",
            "formatted": "2025-02-21"
        }
    ],
    "customData": []
}
 

Request   

GET products/{serviceId}/m365/subscriptions/end-dates

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Get eligible transitions of an M365 subscription

requires authentication

Returns the subscriptions the given subscription can be upgraded to. Use "ProductSku" of an item as "target_product_sku" in "Upgrade an M365 subscription".

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/transitions" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/transitions"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/transitions';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/transitions'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "",
    "data": [
        {
            "ProductSku": "CFQ7TTC0LDPB:0002",
            "Title": "Microsoft 365 Business Premium",
            "TransitionScheduleType": "Immediate",
            "Eligibilities": [
                {
                    "IsEligible": true,
                    "TransitionType": "transition_with_license_transfer",
                    "Errors": []
                }
            ]
        }
    ],
    "customData": []
}
 

Request   

GET products/{serviceId}/m365/subscription/{subscriptionId}/transitions

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

subscriptionId   string     

Subscription ID. Example: 9cb50556-0000-40000-0000-3fdcc63ad0fd

Suspend an M365 subscription

requires authentication

Microsoft processes the change asynchronously: the response carries the order that was placed ("ErpOrderId"), the status of the subscription follows a while later. Poll "Get list of User's M365 subscriptions" to see the new status.

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/suspend" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/suspend"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/suspend';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/suspend'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Subscription has been suspended!",
    "data": {
        "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d",
        "SubscriptionId": "9cb50556-0000-40000-0000-3fdcc63ad0fd",
        "Status": 2
    },
    "customData": []
}
 

Example response (404):


{
    "success": false,
    "message": "Not found Subscription",
    "data": [],
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/subscription/{subscriptionId}/suspend

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

subscriptionId   string     

Subscription ID. Example: 9cb50556-0000-40000-0000-3fdcc63ad0fd

Reactivate a suspended M365 subscription

requires authentication

Processed asynchronously by Microsoft, see "Suspend an M365 subscription".

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/reactivate" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/reactivate"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/reactivate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/reactivate'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Subscription has been reactivated!",
    "data": {
        "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d",
        "SubscriptionId": "9cb50556-0000-40000-0000-3fdcc63ad0fd",
        "Status": 0
    },
    "customData": []
}
 

Example response (404):


{
    "success": false,
    "message": "Not found Subscription",
    "data": [],
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/subscription/{subscriptionId}/reactivate

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

subscriptionId   string     

Subscription ID. Example: 9cb50556-0000-40000-0000-3fdcc63ad0fd

Cancel an M365 subscription

requires authentication

Cancelling is only accepted by Microsoft within the cancellation window of the subscription, see "cancellationAllowedUntilDate" in "Get list of User's M365 subscriptions". Processed asynchronously by Microsoft, see "Suspend an M365 subscription".

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/cancel" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/cancel"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/cancel';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/cancel'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Subscription has been cancelled!",
    "data": {
        "Success": true,
        "ResultMessage": "",
        "Result": null
    },
    "customData": []
}
 

Example response (404):


{
    "success": false,
    "message": "Not found Subscription",
    "data": [],
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/subscription/{subscriptionId}/cancel

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

subscriptionId   string     

Subscription ID. Example: 9cb50556-0000-40000-0000-3fdcc63ad0fd

Upgrade an M365 subscription

requires authentication

Transitions the subscription to another product. The target product must be one of the eligible transitions returned by "Get eligible transitions of an M365 subscription". Microsoft decides whether the transition happens immediately or at the end of the term, and processes it asynchronously, see "Suspend an M365 subscription".

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/upgrade" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"target_product_sku\": \"CFQ7TTC0LDPB:0002\",
    \"quantity\": 1,
    \"term_duration\": \"P1M\",
    \"billing_cycle\": \"P1M\",
    \"transition_type\": \"transition_with_license_transfer\"
}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/upgrade"
);

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

let body = {
    "target_product_sku": "CFQ7TTC0LDPB:0002",
    "quantity": 1,
    "term_duration": "P1M",
    "billing_cycle": "P1M",
    "transition_type": "transition_with_license_transfer"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/upgrade';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'target_product_sku' => 'CFQ7TTC0LDPB:0002',
            'quantity' => 1,
            'term_duration' => 'P1M',
            'billing_cycle' => 'P1M',
            'transition_type' => 'transition_with_license_transfer',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/subscription/9cb50556-0000-40000-0000-3fdcc63ad0fd/upgrade'
payload = {
    "target_product_sku": "CFQ7TTC0LDPB:0002",
    "quantity": 1,
    "term_duration": "P1M",
    "billing_cycle": "P1M",
    "transition_type": "transition_with_license_transfer"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Subscription has been upgraded!",
    "data": {
        "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d",
        "SubscriptionId": "9cb50556-0000-40000-0000-3fdcc63ad0fd",
        "TargetProductSku": "CFQ7TTC0LDPB:0002"
    },
    "customData": []
}
 

Example response (422):


{
    "success": false,
    "message": "Subscription can not be upgraded to CFQ7TTC0LDPB:0002",
    "data": {
        "eligible_product_skus": [
            "CFQ7TTC0LDPB:0003"
        ]
    },
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/subscription/{subscriptionId}/upgrade

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

subscriptionId   string     

Subscription ID. Example: 9cb50556-0000-40000-0000-3fdcc63ad0fd

Body Parameters

target_product_sku   string     

Product SKU to upgrade to, taken from the eligible transitions. Example: CFQ7TTC0LDPB:0002

quantity   integer  optional    

Quantity, Must between 1-10000. Defaults to the current quantity of the subscription. Example: 1

term_duration   string  optional    

Term Duration.
Available options: P1M,P1Y,P3Y,P1X. Defaults to the current term duration of the subscription. Example: P1M

billing_cycle   string  optional    

Billing Duration.
Available options: P1M,P1Y,P3Y,P1X. Defaults to the current billing cycle of the subscription. Example: P1M

transition_type   string  optional    

Transition type.
Available options: transition_only,transition_with_license_transfer. Defaults to the best type the target product is eligible for. Example: transition_with_license_transfer

Get the planned M365 subscription orders of a service

requires authentication

Only orders that still have to be placed are returned, so an order disappears from this list once Nomeo has placed it at Microsoft.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/1/m365/planned-orders" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/planned-orders"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/planned-orders';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/planned-orders'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "",
    "data": [
        {
            "id": 12,
            "plan_date": "2026-09-01",
            "status": 1,
            "status_message": null,
            "licenses": [
                {
                    "quantity": 1,
                    "offer_id": "CFQ7TTC0LH16:0001",
                    "term_duration": "P1M",
                    "billing_cycle": "P1M",
                    "product_id": "77",
                    "friendly_name": "Exchange Online (Plan 1)"
                }
            ]
        }
    ],
    "customData": []
}
 

Request   

GET products/{serviceId}/m365/planned-orders

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Plan an M365 subscription order for a future date

requires authentication

The order is placed by Nomeo on "plan_date", not now. Until then it can be listed and cancelled. Order for today through "Add a new M365 subscription" instead.

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/planned-order" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"catalog_id\": 77,
    \"quantity\": 1,
    \"term_duration\": \"P1M\",
    \"billing_cycle\": \"P1M\",
    \"plan_date\": \"2026-09-01\"
}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/planned-order"
);

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

let body = {
    "catalog_id": 77,
    "quantity": 1,
    "term_duration": "P1M",
    "billing_cycle": "P1M",
    "plan_date": "2026-09-01"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/planned-order';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'catalog_id' => 77,
            'quantity' => 1,
            'term_duration' => 'P1M',
            'billing_cycle' => 'P1M',
            'plan_date' => '2026-09-01',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/planned-order'
payload = {
    "catalog_id": 77,
    "quantity": 1,
    "term_duration": "P1M",
    "billing_cycle": "P1M",
    "plan_date": "2026-09-01"
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Planned order has been added!",
    "data": {
        "id": 12,
        "plan_date": "2026-09-01",
        "status": 1,
        "status_message": null,
        "licenses": [
            {
                "quantity": 1,
                "offer_id": "CFQ7TTC0LH16:0001",
                "term_duration": "P1M",
                "billing_cycle": "P1M",
                "product_id": "77",
                "friendly_name": "Exchange Online (Plan 1)"
            }
        ]
    },
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/planned-order

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Body Parameters

catalog_id   integer     

Subscription Catalog Id. You can get Subscription Catalog Id in "Get Subscription Catalog" API. Example: 77

quantity   integer     

Quantity, Must between 1-10000. Example: 1

term_duration   string     

Term Duration.
Available options: P1M,P1Y,P3Y,P1X. Example: P1M

billing_cycle   string     

Billing Duration.
Available options: P1M,P1Y,P3Y,P1X. Example: P1M

plan_date   string     

Date the order has to be placed on, format Y-m-d, must be after today. Example: 2026-09-01

Cancel a planned M365 subscription order

requires authentication

Only possible as long as the order has not been placed at Microsoft yet.

Example request:
curl --request DELETE \
    "https://api.nomeo.com/products/1/m365/planned-order/12" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/planned-order/12"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/planned-order/12';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/planned-order/12'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "Planned order has been cancelled!",
    "data": [],
    "customData": []
}
 

Example response (404):


{
    "success": false,
    "message": "Not found planned order",
    "data": [],
    "customData": []
}
 

Request   

DELETE products/{serviceId}/m365/planned-order/{plannedOrderId}

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

plannedOrderId   integer     

Planned order id, from "Get the planned M365 subscription orders of a service". Example: 12

Get the GDAP relationships of an M365 tenant

requires authentication

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/1/m365/gdap/relationships" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/gdap/relationships"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/gdap/relationships';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/gdap/relationships'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "",
    "data": [
        {
            "CurrentStatus": "SecurityGroupAdded",
            "ForceCHW": true,
            "Id": 7773,
            "IsTest": false,
            "RelationshipEndDate": "2028-06-04T14:08:13Z",
            "RelationshipId": "99b1f608-0000-0000-0000-16cf1563f7c6-649c51c4-0000-0000-0000-f7c104d0189f",
            "ResellerId": 19,
            "TenantId": "fe1403d5-0000-0000-0000-7cded881c91d"
        }
    ],
    "customData": []
}
 

Request   

GET products/{serviceId}/m365/gdap/relationships

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Add a GDAP relationship for an M365 tenant

requires authentication

Requests a new delegated admin relationship. The response contains the invitation link the customer has to approve before the relationship becomes active.

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/gdap/relationship" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/gdap/relationship"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/gdap/relationship';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/gdap/relationship'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "GDAP relationship has been requested!",
    "data": "https://admin.microsoft.com/AdminPortal/Home#/partners/invitation/granularAdminRelationships/cc0e01d0-0000-0000-0000-9be1c1f0c0a3",
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/gdap/relationship

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Get the Azure subscription of an M365 tenant

requires authentication

"current_total_estimate" is the consumption of the running billing period as estimated by Microsoft, it is not a final invoice amount.

Example request:
curl --request GET \
    --get "https://api.nomeo.com/products/1/m365/azure" \
    --header "Authorization: Bearer {access token}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/azure"
);

const headers = {
    "Authorization": "Bearer {access token}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/azure';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/azure'
headers = {
  'Authorization': 'Bearer {access token}'
}

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

Example response (200):


{
    "success": true,
    "message": "",
    "data": {
        "tenant_id": "fe1403d5-0000-0000-0000-7cded881c91d",
        "azure_subscription_id": "9cb50556-0000-40000-0000-3fdcc63ad0fd",
        "has_azure": true,
        "has_azure_plan": true,
        "is_accessible": true,
        "admin_has_owner_role": true,
        "budget_amount": 500,
        "current_total_estimate": 123.45,
        "billing_start_date": "2024-02-01",
        "billing_end_date": "2024-02-29"
    },
    "customData": []
}
 

Request   

GET products/{serviceId}/m365/azure

Headers

Authorization        

Example: Bearer {access token}

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Set the monthly budget of an Azure subscription

requires authentication

The budget is used by Microsoft to notify about the consumption of the tenant, it does not stop the consumption when it is reached.

Example request:
curl --request POST \
    "https://api.nomeo.com/products/1/m365/azure/budget" \
    --header "Authorization: Bearer {access token}" \
    --header "Content-Type: application/json" \
    --data "{
    \"amount\": 500
}"
const url = new URL(
    "https://api.nomeo.com/products/1/m365/azure/budget"
);

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

let body = {
    "amount": 500
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.nomeo.com/products/1/m365/azure/budget';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {access token}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'amount' => 500.0,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.nomeo.com/products/1/m365/azure/budget'
payload = {
    "amount": 500
}
headers = {
  'Authorization': 'Bearer {access token}',
  'Content-Type': 'application/json'
}

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

Example response (200):


{
    "success": true,
    "message": "Azure budget has been updated!",
    "data": {
        "tenant_id": "fe1403d5-0000-0000-0000-7cded881c91d",
        "budget_amount": 500
    },
    "customData": []
}
 

Request   

POST products/{serviceId}/m365/azure/budget

Headers

Authorization        

Example: Bearer {access token}

Content-Type        

Example: application/json

URL Parameters

serviceId   integer     

Service ID. You can get Service id in "Get list of Partner's Services" API. Example: 1

Body Parameters

amount   number     

Monthly budget in euro. Example: 500

Webhooks guide

Webhooks let your application receive a notification the moment something changes — a new client, a domain update, a product order, a Microsoft tenant change — instead of polling the API. When an event occurs we send an HTTP POST to the URL you configure.

Setting your webhook URL

Configure your webhook in the partner portal under Partner settings → Webhooks:

Source IP

All webhook calls originate from a fixed set of IP addresses. Contact support for the current list and allow-list it on your endpoint/firewall.

Request format

POST {your_webhook_url}
Content-Type: application/json
X-Webhook-Event: <resource_type>.<action>     e.g. domain.nameserverchange
X-Webhook-Id: <event uuid>
X-Webhook-Timestamp: <ISO 8601 UTC>
X-Webhook-Signature: sha256=<hmac>

Body:

{
  "event_id": "f7c1e0e2-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "occurred_at": "2026-05-29T09:12:33Z",
  "resource_type": "domain",
  "resource_id": "12345",
  "action": "nameserverchange"
}

X-Webhook-Id / event_id is unique per event — use it to deduplicate, since a delivery may be retried.

resource_id is always a string (a WHMCS id such as "12345", or a Microsoft tenant GUID for tenant events). The payload is intentionally minimal — fetch the full record from the API using resource_type + resource_id when you need details.

Verifying the signature

Each request is signed with HMAC-SHA256 over the raw request body using your signing secret. Recompute it and compare:

$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $yourSecret);
if (! hash_equals($expected, $request->header('X-Webhook-Signature'))) {
    abort(401);
}
import hmac, hashlib
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()

Resource types, ids and actions

resource_type resource_id actions
client client id newclient, updatedclient, statuschange
domain domain id newdomain, renew, nameserverchange, zoneupdated, statuschange¹
product product (service) id newproduct, statuschange¹, renewproduct¹
tenant product (service) id created, mca, newsubscription, updatedsubscription

¹ Coming soon — not yet delivered. Build your integration to tolerate unknown action values (ignore what you don't handle); these will start arriving without further notice.

domain.zoneupdated means the DNS zone of that domain changed — a record added, changed or removed, a DNS template applied, a TTL change, a zone-file import, a snapshot restore, or the e-mail-forwarding records being linked or unlinked. It covers changes made in the customer portal as well as through this API.

One edit can rewrite many records at once (bulk edit, zone import), so the events are coalesced: a zone raises at most one zoneupdated every 10 seconds. The event does not say what changed — fetch the zone with GET /domains/{domain}/records when you receive it.

Changing the nameservers of a domain raises nameserverchange, not zoneupdated.

For tenant events the resource_id is the WHMCS service id of the Microsoft 365 product — the id the Microsoft endpoints of this API take (/products/{serviceId}/m365/...), not the Microsoft tenant GUID. updatedsubscription covers every change to an existing subscription: quantity, upgrade or downgrade, auto-renew, scheduled renewal changes, extended service term, and cancellation.

Delivery, retries and limits

Respond quickly with a 2xx and process asynchronously on your side if needed.

Best practices

Example receiver (PHP)

$raw = file_get_contents('php://input');

// 1. Verify the signature
$expected = 'sha256=' . hash_hmac('sha256', $raw, $yourSecret);
if (! hash_equals($expected, $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit;
}

$event = json_decode($raw, true);

// 2. Deduplicate (at-least-once) — skip if you've already seen this event_id
if (alreadyProcessed($event['event_id'])) {
    http_response_code(200);
    exit;
}

// 3. Acknowledge immediately, then process asynchronously
http_response_code(200);
fastcgi_finish_request(); // return 2xx now; keep working after

markProcessed($event['event_id']);
handle($event); // e.g. re-fetch $event['resource_type'] #$event['resource_id'] from the API

Reviewing deliveries

The portal's Webhook logs page shows the last 100 delivery attempts (event id, date/time, resource type, resource id, HTTP status code).

Trying it out

The Test button next to the webhook URL sends a sample with "resource_type": "test", "action": "test" and shows the HTTP status your endpoint answered with. Testing a webhook that is already saved signs the sample with that webhook's own secret, so you can verify the signature exactly as you will for real events; testing a URL before saving uses a throwaway secret, so the signature check will not match yet — save first if you want to test verification.

If you need a realistic event for a specific resource type while building your integration, ask support: we can send you a real, signed event for any resource type and action listed above, on request.