MyDNSHost API
This document describes the current API (Version 1.0) for MyDNSHost.
You can use this guide to learn how to interact with the API yourself, or you can use one of the pre-written API libraries:
-
PHP: https://github.com/mydnshost/mydnshost-php-api (This is what the default frontend uses to interact with the api)
User Authentication
There are multiple ways that you can authenticate to the API.
Unless otherwise documented, all end-points require authentication.
Basic Auth
Authentication with the account username/password can be done using HTTP Basic Auth.
Authentication in this manner gives you full access to the account (Similar to as an API Key with all permissions set to true).
If a 2FA Key is required for the account, this must be passed as a HTTP Header:
X-2FA-Key: 123456
Devices can be saved as Trusted Devices to allow them to bypass the need to enter the 2FA key every time.
This can be done by passing a X-2FA-SAVE-DEVICE
header when logging in with a valid 2FA Key:
X-2FA-SAVE-DEVICE: Some Device Name
The API Response will then include a device_id item that can be stored and used for future logins in place of the 2FA Key:
X-2FA-DEVICE-ID: 84FDBE2B-0FB2-461C-9E7B-31A2AF5E52F6
If a X-2FA-DEVICE-ID
is passed alongside the X-2FA-SAVE-DEVICE
header then that device ID will be used to remember the device, otherwise the API will generate a new one for you.
API Key Authentication
If you have a valid API Key, this can be used instead of Basic Auth and offers greater control over what end points can be accessed.
API Keys can be limited as to what they can see/do.
-
domains_read: Has access to
GET
on/domains
end-points -
domains_write: Has access to
POST
orDELETE
on/domains
end-points -
user_read: Has access to
GET
on/users
end-points -
user_write: Has access to
POST
orDELETE
on/users
end-points
You can log in using an API Key by adding the following headers:
X-API-User: SomeUser@example.org
X-API-Key: ede99f46-198a-411a-b066-5f1c92a6d26d
You can also use a domain-key, which behaves like an API key that has no user_read
or user_write
permissions, and can only interact with a single domain. Domain keys are linked to domains not users.
X-Domain: example.org
X-Domain-Key: 9426F536-2559-4FA0-BA50-644C90B5FAE4
These can also be used with basic auth (provide the key as the password and the username/domain as the username) and will behave as if they were passed in via the appropriate HTTP Headers.
Session Authentication
After logging in with one of the above methods, You can obtain a session token from the /session
end point, and then use it for future requests by passing the X-SESSION-ID header instead of any other authentication headers.
X-SESSION-ID: 9pbobqkbiqvhll2ngia8bg0ijd
Session tokens will expire approximately 15 minutes after they were last used, or if the method used to acquire it becomes invalid.
JWT Authentication
After logging in with one of the above methods, You can obtain a jwt token from the /session/jwt
end point, and then use it for future requests by passing the it as a bearer token within the ‘Authorization’ HTTP Header instead of any other authentication headers.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1NjEzMjgzMTQsImV4cCI6MTU2MTMzMTkxNCwiaXNzIjoiTXlETlNIb3N0X2xvY2FsIiwiYWNjZXNzIjpbXSwidXNlcmlkIjoiMSIsIm5vbmNlIjo2MTg2MjYxNjZ9.azz80sLue0OtRCFZS9X5A5r2Lw-k21Shdih7U5NjGk8
JWT tokens will expire approximately 1 hour after they were issued, or if the method used to acquire it becomes invalid.
Request-ID
For any of the requests, you can pass a X-Request-ID header:
X-Request-ID: SomeUniqueID
Which will be returned in the body of any response as a reqid
field, this can be useful if performing async requests to the API. If no specific Request-ID is specified, one will be generated.
Rate Limiting
Requests to the API may be subject to rate limiting. The API uses standard rate-limiting headers to denote the rate limit information, for examples:
X-RateLimit-Limit: 1024
X-RateLimit-Remaining: 512
X-RateLimit-Reset: 1508738400
These will show your total request limit amount for this window, how many requests you have remaining in the window, and the time that the limit resets.
If you have exceeded your limit you will receive a HTTP Error 429 message instead of the usual API response.
Different keys/users may have different limits. If you need a greater limit, please get in touch.
General ¶
General API Endpoints.
API Ping ¶
Ping the APIGET/ping/{time}
This tests that the API is up and running. The API will respond with a non-error and include the time if provided, this does not require authentication.
Example URI
- time
number
(optional) Example: 123456The current time, will be echoed back.
200
If the time is not provided, then the response field is ommited entirely.
Headers
Content-Type: application/json
Body
{
"respid": "58bcb5e953b5d",
"method": "ping/123456",
"response": {
"time": "123456"
}
}
Get the current user information ¶
Get User informationGET/userdata
This lets you see what user you are authenticated as and your current access level based on your authentication.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcb98d67ba3",
"method": "userdata",
"response": {
"user": {
"id": "2",
"email": "user@example.org",
"realname": "Some User"
},
"access": {
"domains_read": true,
"domains_write": false,
"user_read": false,
"user_write": false
}
}
}
Get the current api version ¶
Get version informationGET/version
This is used to see what version of the API you are accessing, this does not require authentication.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcb9e378fd6",
"method": "version",
"response": {
"version": "1.0"
}
}
Session tokens ¶
Open a new session and get a session tokenGET/session
This will obtain a new session token for use in future requests.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "58c33b3ec880c",
"method": "session",
"response": {
"session": "rgmc55ghpbhjmv1qg7ub6q3879"
}
}
Close the current sessionDELETE/session
This will close the current session to prevent any future requests.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "58c33b714169b",
"method": "session",
"response": {
"session": ""
}
}
Get a JWT token ¶
Get a JWT TokenGET/session/jwt
This will obtain a new JWT token for use in future requests.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "5d0ffabae9bc6",
"method": "session/jwt",
"response": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1NjEzMjgzMTQsImV4cCI6MTU2MTMzMTkxNCwiaXNzIjoiTXlETlNIb3N0X2xvY2FsIiwiYWNjZXNzIjpbXSwidXNlcmlkIjoiMSIsIm5vbmNlIjo2MTg2MjYxNjZ9.azz80sLue0OtRCFZS9X5A5r2Lw-k21Shdih7U5NjGk8"
}
}
Forgot Password ¶
Initiate a Forgot Password requestPOST/forgotpassword
This will cause an email to be sent to the user with a link to click on to reset their password.
Example URI
Request password reset
Headers
Content-Type: application/json
Body
{
"data": {
"email": "admin@example.org"
}
}
200
The response on success will show a message of success.
Headers
Content-Type: application/json
Body
{
"respid": "5934bda4bb50c",
"method": "forgotpassword",
"response": {
"success": "Password reset was submitted, please check your email for further instructions."
}
}
Forgot Password Confirm ¶
Confirm a Forgot Password requestPOST/forgotpassword/confirm/{userid}
This will confirm a forgot-password request for the given user, a successful confirmation will send the user an email to confirm the password was chagned.
Example URI
- userid
string
(required) Example: 1The user ID.
Confirm password reset
Headers
Content-Type: application/json
Body
{
"data": {
"code": "BcEBEQAxCAMwSQPaKyCH8fNv4RNnS1EiD7rNfIiMHuHmfZvPv8VWTdgJ0egBzx8",
"password": "n3w_p@55w0rd"
}
}
200
The response on success will show a message of success.
Headers
Content-Type: application/json
Body
{
"respid": "5934be2091a0a",
"method": "forgotpassword/confirm/1",
"response": {
"success": "Password was changed, you can now login."
}
}
400
If there is an error with the request you will get an error reply
Headers
Content-Type: application/json
Body
{
"respid": "5934be3c48047",
"method": "forgotpassword/confirm/1",
"error": "User does not require password reset."
}
Register new account ¶
Initiate a registration requestPOST/register
This will cause an email to be sent to the user with a link to click on to confirm their registration.
Example URI
Registration
Headers
Content-Type: application/json
Body
{
"data": {
"email": "user10@example.org",
"realname": "User Ten"
}
}
200
The response on success will show a message of success.
Headers
Content-Type: application/json
Body
{
"respid": "5934bea6b4a1c",
"method": "register",
"response": {
"id": "56",
"email": "user10@example.org",
"realname": "User Ten"
}
}
Registration Confirmation ¶
Confirm a Forgot Password requestPOST/register/confirm/{userid}
This will confirm a registration request for the given user.
Example URI
- userid
string
(required) Example: 56The new user ID.
Confirm registration
Headers
Content-Type: application/json
Body
{
"data": {
"code": "C28E68B6-17A9-4F43-8F03-3CFF519FC3DA",
"password": "n3w_p@55w0rd"
}
}
200
The response on success will show a message of success.
Headers
Content-Type: application/json
Body
{
"respid": "5934bf2bc9a5d",
"method": "register/confirm/56",
"response": {
"success": "Registration was successful, you can now log in."
}
}
400
If there is an error with the request you will get an error reply
Headers
Content-Type: application/json
Body
{
"respid": "5934bf4001861",
"method": "register/confirm/56",
"error": "User does not require verification."
}
Users ¶
Endpoints for dealing with user accounts
User list ¶
Get the list of known usersGET/users
For a user with the manage_users
permission, this will return all the known users. Users without this permission will just see themselves.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcba77c1505",
"method": "users",
"response":[
{
"id": "2",
"email": "user@example.org",
"realname": "Some User"
}
],
}
Manipulate Users ¶
Get information about a specific userGET/users/{userid}
Returns complete information about the requested user if the user has permission to see the requested user.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcba77c1505",
"method": "users",
"response": {
"id": "2",
"email": "user@example.org",
"realname": "Some User"
"disabled": "false",
"permissions": []
}
}
Update information about a specific userPOST/users/{userid}
Allows updating user information on a user account that you have permission to modify. Any fields that are passed in will be updated, fields not passed will be unchanged.
If you have manage_permissions
you can also pass a map of permissions where the key is the permission, and the value is true
or false
to grant/revoke the permission. Permissions not given will be left unchanged. The meta-permission of all
can be used to set the value of all permissions.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
Change realname and Password
Headers
Content-Type: application/json
Body
{
"data": {
"realname": "Some Real User",
"password": "NewPassword"
}
}
200
The response on success will show the user account as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "58bcbc34234e3",
"method": "users/2",
"response": {
"id": "2",
"email": "user@example.org",
"realname": "Some Real Name",
"updated": true
}
}
400
If there is an error you will get an error
key rather than a response
key in the output
Headers
Content-Type: application/json
Body
{
"respid": "58bcbcc7dc8d1",
"method": "users/2",
"error": "Error updating user: 2"
}
Delete a specific userDELETE/users/{userid}
This will allow a user with the manage_users
permission to delete the user specified, or allow a user to delete themselves. If self-deleting is enabled and you try to delete the current user, the API will give you a confirm code that you need to use to perform a confirmed delete.
Deleting a user will disassociate them with any domains, but will not remove the domains.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcbde798d3a",
"method": "users/2",
"response": {
"deleted": "true"
}
}
Confirm delete the current user ¶
This endpoint is used to perform a confirmed delete of a given user.
Deleting a user will disassociate them with any domains, but will not remove the domains.
Confirm delete the current userDELETE/users/{userid}/confirm/{confirmcode}
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
- confirmcode
string
(required) Example: c00696d9The confirm code provided by the initial delete attempt.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcbde798d3a",
"method": "users/2/confirm/c00696d9",
"response": {
"deleted": "true"
}
}
Confirm delete the current user with 2FA ¶
This endpoint is used to perform a confirmed delete of a given user who has 2fa enabled.
Deleting a user will disassociate them with any domains, but will not remove the domains.
Confirm delete the current user with 2FADELETE/users/{userid}/confirm/{confirmcode}/{twofactorcode}
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
- confirmcode
string
(required) Example: c00696d9The confirm code provided by the initial delete attempt.
- twofactorcode
string
(required) Example: 123456A valid 2FA code for this user.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcbde798d3a",
"method": "users/2/confirm/c00696d9/123456",
"response": {
"deleted": "true"
}
}
Create a user ¶
Create a userPOST/users/create
This allows a user with the manage_users
permission to create new users.
This behaves similarly to update user except that you must pass in the email
and realname
fields.
You can also either pass in a password
field to set the password, or to simulate a user registration you can pass in sendWelcome
with a value of true
Example URI
Change realname and Password
Headers
Content-Type: application/json
Body
{
"data": {
"email": "newuser@example.org",
"realname": "Some new User",
"password": "NewPassword"
}
}
200
The response on success will show the user account as it exists after creation.
Headers
Content-Type: application/json
Body
{
"respid": "58bcbe6b76cee",
"method": "users/create",
"response": {
"id": "6",
"email": "newuser@example.org",
"realname": "Some new User",
"updated": true
}
}
400
On error, you will get an error
rather than a response
Headers
Content-Type: application/json
Body
{
"respid": "58bcbe8c7ac06",
"method": "users/create",
"error": "Error creating user."
}
Resend Welcome Message ¶
Request a welcome email be resent to a user.POST/users/{userid}/resendwelcome
If a user is still pending verification, we can re-send the welcome email to them. (This requires the manage_users
permission)
Example URI
- userid
string
(required) Example: 1The user ID.
request a welcome email be resent
The body of this request is empty
Headers
Content-Type: application/json
200
The response on success will show a message of success.
Headers
Content-Type: application/json
Body
{
"respid": "5934c0a6e5bf3",
"method": "users/56/resendwelcome",
"response": {
"success": "Registration email resent."
}
}
400
If there is an error with the request you will get an error reply
Headers
Content-Type: application/json
Body
{
"respid": "5934c05e6b420",
"method": "users/56/resendwelcome",
"error": "User has already completed registration."
}
Accept terms of service ¶
Accept terms of service.POST/users/{userid}/acceptterms
If a user has not accepted the terms of service this allows them to do so. (This requires the user_write
permission)
Example URI
- userid
string
(required) Example: selfThe user ID (must be own user account or “self”).
Accept terms of service
Headers
Content-Type: application/json
Body
{
"data": {
"acceptterms": "true"
}
}
200
The response on success will show a message of success.
Headers
Content-Type: application/json
Body
{
"respid": "5b1df1e976654",
"method": "users/self/acceptterms",
"response":{
"acceptterms": "Terms accepted."
},
}
400
If there is an error with the request you will get an error reply
Headers
Content-Type: application/json
Body
{
"respid": "5b1df1e976654",
"method": "users/self/resendwelcome",
"error": "There was an error accepting the terms of service."
}
API Keys ¶
Get known API KeysGET/users/{userid}/keys
Returns the list of known API Keys and their description/permissions.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bf2439319ea",
"method": "users/self/keys",
"response": {
"F4C108DA-4070-45A4-8223-8C5DDFB96A51": {
"description": "Test Key",
"domains_read": "true",
"domains_write": "true",
"user_read": "true",
"user_write": "true"
},
"60B56841-508D-4037-9A16-B234B9E849A0": {
"description": "Domains Read-Only Key",
"domains_read": "true",
"domains_write": "false",
"user_read": "false",
"user_write": "false"
}
}
}
Create a new KeyPOST/users/{userid}/keys
Create a new API Key. The key itself will be randomly generated and returned.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
Create a key that has read-only access to just /domains
Headers
Content-Type: application/json
Body
{
"data": {
"description": "Domains Read-Only Key",
"domains_read": "true"
}
}
200
The response on success will show the newly created key
Headers
Content-Type: application/json
Body
{
"respid": "58bf24e7d5638",
"method": "users/self/keys",
"response": {
"60B56841-508D-4037-9A16-B234B9E849A0": {
"description": "Domains Read-Only Key",
"domains_read": "true",
"domains_write": false,
"user_read": false,
"user_write": false,
"updated": true
}
}
}
Manipulate specific API Key ¶
Get key description/permissionsGET/users/{userid}/keys/{keyid}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 00413A9B-E086-4AD7-AC82-FF061B28D176The key ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bf257073446",
"method": "users/self/keys/00413A9B-E086-4AD7-AC82-FF061B28D176",
"response": {
"description": "Domains Read-Only Key",
"domains_read": "true",
"domains_write": "false",
"user_read": "false",
"user_write": "false"
}
}
Update keyPOST/users/{userid}/keys/{keyid}
This takes the same parameters as create, but will update an existing key.
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 00413A9B-E086-4AD7-AC82-FF061B28D176The key ID.
Update a key
Headers
Content-Type: application/json
Body
{
"data": {
"description": "Full-Access Key",
"domains_read": "true",
"domains_write": "true",
"user_read": "true",
"user_write": "true"
}
}
200
The response on success will show the key as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "58bf24e7d5638",
"method": "users/self/keys/00413A9B-E086-4AD7-AC82-FF061B28D176",
"response": {
"description": "Full-Access Key",
"domains_read": "true",
"domains_write": "true",
"user_read": "true",
"user_write": "true",
"updated": true
}
}
Delete keyDELETE/users/{userid}/keys/{keyid}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 00413A9B-E086-4AD7-AC82-FF061B28D176The key ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bf2602687cc",
"method": "users/self/keys/00413A9B-E086-4AD7-AC82-FF061B28D176",
"response": {
"deleted": "true"
}
}
2FA Keys ¶
Get known 2FA KeysGET/users/{userid}/2fa
Returns the list of known 2FA Key-IDs and information about them.
Keys that have not yet been verified will also include the secret to allow a QR Code to be displayed if appropriate.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
200
Headers
Content-Type: application/json
Body
{
"respid": "591e43446c4b7",
"method": "users/self/2fa",
"response": {
"1": {
"description": "Test Key",
"created": "1495151997",
"lastused": "1495153158",
"active": "true"
},
"2": {
"key": "MCOERRKFPJ7Z2Q2U",
"description": "Second Key",
"created": "1495151997",
"lastused": "0",
"active": "false"
}
}
}
Create a new KeyPOST/users/{userid}/2fa
Create a new 2FA Key.
We support multiple types of code, ‘rfc6238’ (Default), ‘plain’ and ‘yubikeyotp’.
If no ‘type’ data parameter is provided, then ‘rfc6238’ is assumed.
For ‘rfc6238’ and ‘plain’, the secret will be randomly generated.
For ‘yubikeyotp’ an OTP must be provided that validates against yubico cloud.
If no ‘onetime’ data parameter is provided, then ‘false’ is assumed, otherwise the key will only be valid for a single use.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
Create a key
Headers
Content-Type: application/json
Body
{
"data": {
"description": "Third Key",
"type": "rfc6238",
"onetime": false
}
}
200
The response on success will show the newly created key
Headers
Content-Type: application/json
Body
{
"respid": "591e43b1d0df7",
"method": "users/self/2fa",
"response": {
"id": "6",
"key": "7QEAT6ARPO4TKVUC",
"description": "Third Key",
"created": 1495155633,
"lastused": 0,
"active": false,
"type": "rfc6238",
"onetime": false,
"updated": true
}
}
Manipulate specific 2FA Key ¶
Get key description/permissionsGET/users/{userid}/2fa/{keyid}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 6The key ID.
200
The “key” parameter will only be returned if the key is not yet active.
Headers
Content-Type: application/json
Body
{
"respid": "591e43f5ce743",
"method": "users/self/2fa/6",
"response": {
"id": "6",
"key": "7QEAT6ARPO4TKVUC",
"description": "Third Key",
"created": "1495155633",
"lastused": "0",
"active": "false"
}
}
Update keyPOST/users/{userid}/2fa/{keyid}
This takes the same parameters as create, but will update an existing key.
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 6The key ID.
Update a key
Headers
Content-Type: application/json
Body
{
"data": {
"description": "Third Device"
}
}
200
The response on success will show the key as it exists after the change. The “key” parameter will only be returned if the key is not yet active.
Headers
Content-Type: application/json
Body
{
"respid": "591e444c2868c",
"method": "users/self/2fa/6",
"response": {
"id": "6",
"key": "7QEAT6ARPO4TKVUC",
"description": "Third Device",
"created": "1495155633",
"lastused": "0",
"active": "false",
"updated": true
}
}
Delete keyDELETE/users/{userid}/2fa/{keyid}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 6The key ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "591e456fdb62f",
"method": "users/self/2fa/6",
"response": {
"deleted": "true"
}
}
Verify 2FA Key ¶
Verify 2FA KeyPOST/users/{userid}/2fa/{keyid}/verify
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- keyid
string
(required) Example: 6The key ID.
Verify a key
Headers
Content-Type: application/json
Body
{
"data": {
"code": "123456"
}
}
200
Headers
Content-Type: application/json
Body
{
"respid": "591e453d08ac9",
"method": "users/self/2fa/6/verify",
"response": {
"success": "Valid code provided."
}
}
40 01
Headers
Content-Type: application/json
Body
{
"respid": "591e455409613",
"method": "users/self/2fa/6/verify",
"error": "Invalid code provided for verification."
}
2FA Devices ¶
2FA Devices are devices that have passed the 2FA check in the past and the user has chosen to allow them to login without 2fa.
Get known 2FA DevicesGET/users/{userid}/2fadevices
Returns the list of known 2FA Devices and information about them.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
200
Headers
Content-Type: application/json
Body
{
"respid": "5a1af9caaffc6",
"method": "users/self/2fadevices",
"response":{
"1":{
"description": "Some Device",
"created": "1511715554",
"lastused": "1511715554",
},
"2":{
"description": "Some Other Device",
"current": true,
"created": "1511717965",
"lastused": "1511717965",
}
}
}
Manipulate specific 2FA Device ¶
Delete keyDELETE/users/{userid}/2fadevices/{deviceid}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- deviceid
string
(required) Example: 6The Device ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "5a1afd4852d97",
"method": "users/self/2fadevices/6",
"response": {
"deleted": "true"
}
}
User custom data {DEPRECATED} ¶
This allows applications to store user-specific data within the api. This is deprecated in favour of userdata within the user information endpoints
Get known custom data {DEPRECATED}GET/users/{userid}/customdata
Returns the list of known Custom-Data Key/Value pairs.
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
200
Headers
Content-Type: application/json
Body
{
"respid": "59c7bac0c46e5",
"method": "users/self/customdata",
"response": {
"test.ing": "testValue 2",
"test.ing3": "testValue 3",
"uk.co.mydnshost.www/domain/defaultpage": "records"
}
}
Manipulate specific custom data key/value {DEPRECATED} ¶
Get key value {DEPRECATED}GET/users/{userid}/customdata/{key}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- key
string
(required) Example: test.ingThe custom data key.
200
Headers
Content-Type: application/json
Body
{
"respid": "59c7baf524aac",
"method": "users/self/customdata/test.ing",
"response": {
"key": "test.ing",
"value": "testValue 2"
}
}
Create/Update custom data for key {DEPRECATED}POST/users/{userid}/customdata/{key}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- key
string
(required) Example: test.ingThe custom data key.
Update custom data
Headers
Content-Type: application/json
Body
{
"data": {
"value": "Some Value"
}
}
200
The response on success will show the data as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "59c7bb169ac68",
"method": "users/self/customdata/test.ing",
"response": {
"key": "test.ing",
"value": "Some Value",
"updated": true
}
}
Delete key {DEPRECATED}DELETE/users/{userid}/customdata/{key}
Example URI
- userid
string
(required) Example: selfThe user ID. This can also be “self” for the current user.
- key
string
(required) Example: test.ingThe custom data key.
200
Headers
Content-Type: application/json
Body
{
"respid": "59c7bb2d0cfd5",
"method": "users/self/customdata/test.ing"
"response":{
"deleted": "true"
}
}
User Domain Statistics ¶
Get statistics for all our domainsGET/users/{userid}/stats/{stattype}{?type}
Example URI
- userid
string
(required) Example: 2The user ID. This can also be “self” for the current user.
- stattype
string
(required) Example: domains- type
string
(required) Example: raw
200
Headers
Content-Type: application/json
Body
{
"respid": "59c7c79a96fd3",
"method": "/users/self/stats/domains",
"response":{
"stats": {
"example.org": [{"time": 1505074560, "value": 249101},
{"time": 1505074620, "value": 249122},
{"time": 1505074680, "value": 249132},
// More data
{"time": 1505078040, "value": 250476},
{"time": 1505078100, "value": 250497}],
"example.com": [{"time": 1505074560, "value": 97971},
{"time": 1505074620, "value": 97975},
{"time": 1505074680, "value": 97975},
// More data
{"time": 1505078040, "value": 98409},
{"time": 1505078100, "value": 98409}],
// More Domain Names
"example.net": [{"time": 1505074560, "value": 176},
{"time": 1505074620, "value": 176},
{"time": 1505074680, "value": 176},
// More data
{"time": 1505078040, "value": 176},
{"time": 1505078100, "value": 176}]
}
}
}
Domains ¶
Endpoints for dealing with domains.
Get domains ¶
Get list of known domainsGET/domains{?contains}
See what domains you have access to, and what level of access to each.
Example URI
- contains
string
(optional) Example: foo.bar.baz.example.comOnly return the domain that would contain this record
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc0357e7eb",
"method": "domains",
"response": {
"example.org": "owner",
"test2.com": "owner",
"example1.org": "write",
"example2.org": "read"
}
}
Create a new domainPOST/domains
If the user has the domains_create
permission, they can use this to create a new domain owned by themselves.
Example URI
Create a domain
Headers
Content-Type: application/json
Body
{
"data": {
"domain": "example.net"
}
}
200
A successful response will display the newly-created domain.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc0c377913",
"method": "domains",
"response": {
"id": "9",
"domain": "example.net",
"defaultttl": 86400,
"disabled": false,
"SOA": {
"primaryNS": "ns1.example.net.",
"adminAddress": "dnsadmin.example.net.",
"serial": "0",
"refresh": "86400",
"retry": "7200",
"expire": "2419200",
"minttl": "60"
}
}
}
400
An error will include an error
and possibly errorData
information.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc115b3601",
"method": "domains",
"error": "Error updating domain.",
"errorData": "Domain already exists."
}
Specific domain infomation ¶
Get information about a domainGET/domains/{domain}
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
A successful response will display information about the domain.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc18455fac",
"method": "domains/example.org",
"response": {
"id": "3",
"domain": "example.org",
"defaultttl": 86400,
"disabled": "false",
"SOA": {
"primaryNS": "ns1.mydnshost.co.uk.",
"adminAddress": "dnsadmin.dataforce.org.uk.",
"serial": "2017030500",
"refresh": "86400",
"retry": "7200",
"expire": "2419200",
"minttl": "60"
}
}
}
400
An error will include an error
rather than the response
Headers
Content-Type: application/json
Body
{
"respid": "58bcc1a902ddd",
"method": "domains/example.example",
"error": "Unknown domain: example.example"
}
Update information about a domainPOST/domains/{domain}
This allows changing the domain enabled/disabled status or updating the SOA fields.
As with other update methods, only fields that are provided will be changed, you do not need to provide a complete object.
Changes made with this end point do not automatically increment the domain serial.
Example URI
- domain
string
(required) Example: example.orgThe domain name
Disable domain and update the serial
Headers
Content-Type: application/json
Body
{
"data": {
"disabled": "true",
"SOA": {
"serial": "999"
}
}
}
200
A successful response will display the newly-updated domain.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc2a9b4b77",
"method": "domains/example.org",
"response": {
"id": "3",
"domain": "example.org",
"defaultttl": 86400,
"disabled": "true",
"SOA": {
"primaryNS": "ns1.mydnshost.co.uk.",
"adminAddress": "dnsadmin.dataforce.org.uk.",
"serial": "999",
"refresh": "86400",
"retry": "7200",
"expire": "2419200",
"minttl": "60"
}
}
}
Delete a domainDELETE/domains/{domain}
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc2d6e7515",
"method": "domains/example.org",
"response": {
"deleted": "true"
}
}
Domain access levels ¶
Get all users with access to the domainGET/domains/{domain}/access
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "58bdf7472d255",
"method": "domains/example2.org/access",
"response": {
"id": "7",
"domain": "example2.org",
"defaultttl": 86400,
"disabled": "false",
"access": {
"admin@example.org": "write",
"user2@example.org": "owner"
}
}
}
Update domain accessPOST/domains/{domain}/access
This allows changing user access levels on the domain.
As a general rule of thumb, you can not edit your own access level, and you can not set people to have an access level equal or above your own (Thus only users with the manage_domains
permission can set domain owners.)
There are 5 levels of access (each level has all the access of those below it):
-
owner - Owner has full control over the domain, there can only be 1. Only the owner can delete the domain.
-
admin - Domain admins can grant other users write access to the domain.
-
write - Write allows changing domain records
-
read - Read allows reading domain records but not changing
-
none - No access to the domain (Default)
Example URI
- domain
string
(required) Example: example.orgThe domain name
Give user1 write access
Headers
Content-Type: application/json
Body
{
"data": {
"access": {
"user1@example.org": "write"
}
}
}
200
A successful response will display the newly-updated access list.
Headers
Content-Type: application/json
Body
{
"respid": "58bdf89ebc587",
"method": "domains/example2.org/access",
"response": {
"id": "7",
"domain": "example2.org",
"defaultttl": 86400,
"disabled": "false",
"access": {
"admin@example.org": "write",
"user2@example.org": "owner",
"user1@example.org": "write"
}
}
}
400
If there is an error changing any of the requested access, the whole change will be aborted with an error message explaining why.
Headers
Content-Type: application/json
Body
{
"respid": "58bdf83ed6cd5",
"method": "domains/example2.org/access",
"error": "You do not have the required access to the domain: example2.org"
}
Domain Keys ¶
Get known Domain KeysGET/domains/{domain}/keys
Returns the list of known Domain Keys and their description/permissions.
Domain keys behave like user API Keys, except they are limited to a single domain and can only be given read or write access (not owner or admin).
You will need write
level access on a domain to view or make changes to domain keys and will need to be authenticated as a real user and not using another domain key.
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "592f821198f95",
"method": "domains/example.org/keys",
"response": {
"9426F536-2559-4FA0-BA50-644C90B5FAE4": {
"description": "Write Key",
"domains_write": "true",
"created": "1496284877",
"lastused": "1496284879"
},
"586DAB85-9DCE-4FA2-AA9D-877AA7011190": {
"description": "Read Key",
"domains_write": "false",
"created": "1496284877",
"lastused": "1496285565"
}
}
}
Create a new KeyPOST/domains/{domain}/keys
Create a new Domain Key. The key itself will be randomly generated and returned.
Example URI
- domain
string
(required) Example: example.orgThe domain name
Create a key that has read-only access
Headers
Content-Type: application/json
Body
{
"data": {
"description": "Read-Only Key"
}
}
200
The response on success will show the newly created key
Headers
Content-Type: application/json
Body
{
"respid": "592f825565d61",
"method": "domains/example.org/keys",
"response": {
"7BACDD7D-31D2-4B01-9D8B-D782CD71BF0E": {
"description": "Read-Only Key",
"domains_write": false,
"created": 1496285781,
"lastused": 0,
"updated": true
}
}
}
Manipulate specific Domain Key ¶
Get key description/permissionsGET/domains/{domain}/keys/{keyid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- keyid
string
(required) Example: 7BACDD7D-31D2-4B01-9D8B-D782CD71BF0EThe key ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "592f828d6ddbd",
"method": "domains/example.org/keys/7BACDD7D-31D2-4B01-9D8B-D782CD71BF0E",
"response": {
"description": "Read-Only Key",
"domains_write": "false",
"created": "1496285781",
"lastused": "0"
}
}
Update keyPOST/domains/{domain}/keys/{keyid}
This takes the same parameters as create, but will update an existing key.
Example URI
- domain
string
(required) Example: example.orgThe domain name
- keyid
string
(required) Example: 7BACDD7D-31D2-4B01-9D8B-D782CD71BF0EThe key ID.
Update a key
Headers
Content-Type: application/json
Body
{
"data": {
"description": "Full-Access Key",
"domains_write": "true"
}
}
200
The response on success will show the key as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "592f82ac75e21",
"method": "domains/example.org/keys/7BACDD7D-31D2-4B01-9D8B-D782CD71BF0E",
"response": {
"description": "Full-Access Key",
"domains_write": "true",
"created": "1496285781",
"lastused": "0",
"updated": true
}
}
Delete keyDELETE/domains/{domain}/keys/{keyid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- keyid
string
(required) Example: 7BACDD7D-31D2-4B01-9D8B-D782CD71BF0EThe key ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "592f82c0d3006",
"method": "domains/example.org/keys/7BACDD7D-31D2-4B01-9D8B-D782CD71BF0E",
"response": {
"deleted": "true"
}
}
Domain Hooks ¶
Get known Domain HooksGET/domains/{domain}/hooks
Returns the list of known Domain Hooks and any password associated with them
Domain Hooks are web pages that recieve specially-crafted POST requests when certain events happen related to a domain.
If a password is specified, the POST request will include an X-HMAC-SIGNATURE header signing the data that was sent.
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "5a1afee40bc4c",
"method": "domains/example.org/hooks",
"response": {
"3": {
"url": "http://hooks.example.org/hook1.php",
"password": "password",
"disabled": "false",
"created": "1511718537",
"lastused": "0"
},
"4": {
"url": "http://hooks.example.org/hook2.php",
"password": "",
"disabled": "false",
"created": "1511718542",
"lastused": "0"
}
}
}
Create a new HookPOST/domains/{domain}/hooks
Create a new Domain Hook.
Example URI
- domain
string
(required) Example: example.orgThe domain name
Create a Hook without a password
Headers
Content-Type: application/json
Body
{
"data": {
"url": "http://hooks.example.org/hook3.php",
"password": ""
}
}
200
The response on success will show the newly created hook
Headers
Content-Type: application/json
Body
{
"respid": "5a1b003293d16",
"method": "domains/example.org/hooks",
"response": {
"5": {
"url": "http://hooks.example.org/hook3.php",
"password": "",
"disabled": false,
"created": 1511718962,
"lastused": 0,
"updated": true
}
}
}
Manipulate specific Domain Hook ¶
Get Hook detailsGET/domains/{domain}/hooks/{hookid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- hookid
string
(required) Example: 5The Hook ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "592f828d6ddbd",
"method": "domains/example.org/hooks/5",
"response": {
"url": "http://hooks.example.org/hook3.php",
"password": "",
"disabled": false,
"created": 1511718962,
"lastused": 0
}
}
Update HookPOST/domains/{domain}/hooks/{hookid}
This takes the same parameters as create, but will update an existing hook.
Example URI
- domain
string
(required) Example: example.orgThe domain name
- hookid
string
(required) Example: 5The Hook ID.
Update a hook
Headers
Content-Type: application/json
Body
{
"data": {
"password": "foo"
}
}
200
The response on success will show the hook as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "5a1b00d645f22",
"method": "domains/example.org/hooks/5",
"response": {
"url": "http://hooks.example.org/hook3.php",
"password": "foo",
"disabled": "false",
"created": "1511718900",
"lastused": "0",
"updated": true
}
}
Delete HookDELETE/domains/{domain}/hooks/{hookid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- hookid
string
(required) Example: 5The Hook ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "592f82c0d3006",
"method": "domains/example.org/hooks/5",
"response": {
"deleted": "true"
}
}
Domain records ¶
Get all domain recordsGET/domains/{domain}/records
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc3059365b",
"method": "domains/example.org/records",
"response": {
"records": [
{
"id": "18",
"name": "",
"type": "A",
"content": "127.0.0.1",
"ttl": "86400",
"priority": null,
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
},
{
"id": "19",
"name": "www",
"type": "A",
"content": "127.0.0.1",
"ttl": "86400",
"priority": null,
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
},
{
"id": "20",
"name": "",
"type": "AAAA",
"content": "::1",
"ttl": "86400",
"priority": null,
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
},
{
"id": "21",
"name": "www",
"type": "AAAA",
"content": "::1",
"ttl": "86400",
"priority": null,
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
},
{
"id": "22",
"name": "txt",
"type": "TXT",
"content": "Some Text Record",
"ttl": "86400",
"priority": null,
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
},
{
"id": "23",
"name": "",
"type": "MX",
"content": "",
"ttl": "86400",
"priority": "10",
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
},
{
"id": "24",
"name": "",
"type": "MX",
"content": "test",
"ttl": "86400",
"priority": "50",
"changed_at": "1488755309",
"changed_by": null,
"disabled": "false"
}
],
"hasNS": true,
"soa": {
"primaryNS": "ns1.mydnshost.co.uk.",
"adminAddress": "dnsadmin.dataforce.org.uk.",
"serial": "999",
"refresh": "86400",
"retry": "7200",
"expire": "2419200",
"minttl": "60"
}
}
}
Update domain recordsPOST/domains/{domain}/records
This can update/delete specifically named records, or add new records all in one go.
You can not edit the SOA from here, and the serial will be incremented automatically.
As with other update methods, only fields that are provided will be changed, you do not need to provide a complete object.
Example URI
- domain
string
(required) Example: example.orgThe domain name
update content for ID 18/19, delete 20 and add a new A record.
Headers
Content-Type: application/json
Body
{
"data": {
"records": [
{
"id": "18",
"content": "127.0.0.18"
},
{
"id": "19",
"content": "127.0.0.18"
},
{
"id": "20",
"delete": true
},
{
"name": "localhost",
"type": "A",
"content": "127.0.0.1",
"ttl": "86400"
}
]
}
}
200
A success response will show the records that were changed, and any new records that were added, along with the new domain serial.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc593acecc",
"method": "domains/example.org/records",
"response": {
"serial": "2017030600",
"changed": [
{
"id": "18",
"name": "",
"type": "A",
"content": "127.0.0.18",
"ttl": "86400",
"priority": null,
"changed_at": 1488766355,
"changed_by": "2",
"disabled": "false",
"updated": true
},
{
"id": "19",
"name": "www",
"type": "A",
"content": "127.0.0.18",
"ttl": "86400",
"priority": null,
"changed_at": 1488766355,
"changed_by": "2",
"disabled": "false",
"updated": true
},
{
"id": "35",
"name": "localhost",
"type": "A",
"content": "127.0.0.1",
"ttl": "86400",
"priority": null,
"changed_at": 1488766355,
"changed_by": "2",
"disabled": false,
"updated": true
},
{
"id": "20",
"deleted": true
}
]
}
}
400
A response will contain errorData to show errors related to specific records passed in. If there are any errors, no changes are made.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc54aca077",
"method": "domains/example.org/records",
"error": "There was errors with the records provided.",
"errorData": {
"1": "Unable to validate record: Content must be a valid IPv4 Address."
}
}
Delete all domain recordsDELETE/domains/{domain}/records
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc5e696495",
"method": "domains/example.org/records",
"response": {
"deleted": 7,
"serial": 2017030601
}
}
Domain Statistics ¶
Get raw statistics for this domainGET/domains/{domain}/stats{?type}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- type
string
(required) Example: raw
200
Headers
Content-Type: application/json
Body
{
"respid": "59b5900b12a2e",
"method": "domains/example.org/stats",
"response":{
"stats": {
"A": [{"time": 1505074560, "value": 249101},
{"time": 1505074620, "value": 249122},
{"time": 1505074680, "value": 249132},
// More data
{"time": 1505078040, "value": 250476},
{"time": 1505078100, "value": 250497}],
"AAAA": [{"time": 1505074560, "value": 97971},
{"time": 1505074620, "value": 97975},
{"time": 1505074680, "value": 97975},
// More data
{"time": 1505078040, "value": 98409},
{"time": 1505078100, "value": 98409}],
// More RR Types
"TXT": [{"time": 1505074560, "value": 176},
{"time": 1505074620, "value": 176},
{"time": 1505074680, "value": 176},
// More data
{"time": 1505078040, "value": 176},
{"time": 1505078100, "value": 176}]
}
}
}
Domain Logs ¶
Get logs for this domainGET/domains/{domain}/logs
Get recent logs related to this domain.
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
Headers
Content-Type: application/json
Body
{
"respid": "5d5afd8092ecf",
"method": "domains/example.org/logs",
"response": [
{
"timestamp": "2019-08-19T19:12:47.710Z",
"message": "19-Aug-2019 19:12:47.709 zone example.org/IN (signed): reconfiguring zone keys"
},
{
"timestamp": "2019-08-19T19:12:47.711Z",
"message": "19-Aug-2019 19:12:47.710 zone example.org/IN (signed): next key event: 19-Aug-2019 20:12:47.709"
}
]
}
Domain export ¶
Export zone as bind zone fileGET/domains/{domain}/export/{type}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- type
string
(optional) Example: bindZone file format to export as (Valid types: bind)
200
Headers
Content-Type: application/json
Body
{
"respid": "58cef4d2a5104",
"method": "domains/example.org/export",
"response": {
"zone": "; Written at Sun, 19 Mar 2017 21:14:58 +0000\n$TTL 86400\n$ORIGIN example.org.\nexample.org. IN SOA ns1.example.org. dnsadmin.example.org. (\n 2017031900\n 86400\n 7200\n 2419200\n 60 )\n\nexample.org. 86400 IN NS dev.mydnshost.co.uk.\nexample.org. 86400 IN A 127.0.0.1\nwww.example.org. 86400 IN A 127.0.0.1\nexample.org. 86400 IN AAAA ::1\nwww.example.org. 86400 IN AAAA ::1\ntest.example.org. 86400 IN CNAME www.example.org.\ntxt.example.org. 86400 IN TXT \"Some Text Record\"\nexample.org. 86400 IN MX 10 example.org.\nexample.org. 86400 IN MX 50 www.example.org.\n"
}
}
Domain import ¶
Export zone as bind zone filePOST/domains/{domain}/import/{type}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- type
string
(optional) Example: bindZone file format to import from (Valid types: bind)
import from zone file
Headers
Content-Type: application/json
Body
{
"data": {
"zone": "; Written at Sun, 19 Mar 2017 21:14:58 +0000\n$TTL 86400\n$ORIGIN example.org.\nexample.org. IN SOA ns1.example.org. dnsadmin.example.org. (\n 2017031900\n 86400\n 7200\n 2419200\n 60 )\n\nexample.org. 86400 IN NS dev.mydnshost.co.uk.\nexample.org. 86400 IN A 127.0.0.1\nwww.example.org. 86400 IN A 127.0.0.1\nexample.org. 86400 IN AAAA ::1\nwww.example.org. 86400 IN AAAA ::1\ntest.example.org. 86400 IN CNAME www.example.org.\ntxt.example.org. 86400 IN TXT \"Some Text Record\"\nexample.org. 86400 IN MX 10 example.org.\nexample.org. 86400 IN MX 50 www.example.org.\n"
}
}
200
If the import is successful, the zone serial will be returned.
Headers
Content-Type: application/json
Body
{
"respid": "58cef5a9d7216",
"method": "domains/example.org/import",
"response": {
"serial": "2017031900"
}
}
Specific domain record information ¶
Get specific record informationGET/domains/{domain}/records/{recordid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- recordid
number
(required) Example: 21The record id
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc673f3c17",
"method": "domains/example.org/records/21",
"response": {
"id": "21",
"name": "www",
"type": "A",
"content": "127.0.0.1",
"ttl": "86400",
"priority": null,
"changed_at": "1488766474",
"changed_by": null,
"disabled": "false"
}
}
Update a specific recordPOST/domains/{domain}/records/{recordid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- recordid
number
(required) Example: 21The record id
Update content
Headers
Content-Type: application/json
Body
{
"data": {
"content": "127.0.0.18"
}
}
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc6cb79998",
"method": "domains/example.org/records/21",
"response": {
"id": "21",
"name": "www",
"type": "A",
"content": "127.0.0.18",
"ttl": "86400",
"priority": null,
"changed_at": 1488766667,
"changed_by": "2",
"disabled": "false"
}
}
400
If there is a validation error, you will get error
and errorData
rather than response
Headers
Content-Type: application/json
Body
{
"respid": "58bcc6df9bd2d",
"method": "domains/example.org/records/21",
"error": "Error updating record.",
"errorData": "Content must be a valid IPv4 Address."
}
Delete a specific recordDELETE/domains/{domain}/records/{recordid}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- recordid
number
(required) Example: 21The record id
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcc701e70d7",
"method": "domains/example.org/records/21",
"response": {
"deleted": "true",
"serial": 2017030601
}
}
400
Headers
Content-Type: application/json
Body
{
"respid": "58bcc75e10e3a",
"method": "domains/example.org/records/21",
"error": "Unknown record id for domain example.org : 21"
}
Specific records by name ¶
Get all `www` records with a type of AGET/domains/{domain}/record/{rrname}/{rrtype}
This allows looking at specific records by name and/or type.
(If rrtype is not specified, then all records of the requested name will be shown, regardless of the type)
Example URI
- domain
string
(required) Example: example.orgThe domain name
- rrname
string
(required) Example: wwwThe record name
- rrtype
string
(optional) Example: AThe record type
200
Headers
Content-Type: application/json
Body
{
"respid": "591b5190e3f66",
"method": "domains/example1.org/record/www/A",
"response": {
"records": [
{
"id": "69",
"name": "www",
"type": "A",
"content": "127.0.0.1",
"ttl": "86400",
"priority": null,
"changed_at": "1490399322",
"changed_by": null,
"disabled": "false"
}
]
}
}
Delete all domain records with a type of ADELETE/domains/{domain}/record/{rrname}/{rrtype}
Example URI
- domain
string
(required) Example: example.orgThe domain name
- rrname
string
(required) Example: wwwThe record name
- rrtype
string
(optional) Example: AThe record type
200
Headers
Content-Type: application/json
Body
{
"respid": "591b51c5a5ca8",
"method": "domains/example1.org/record/www/A",
"response": {
"deleted": 1,
"serial": "2017051600"
}
}
Force backend sync ¶
Force backend syncGET/domains/{domain}/sync
Attempt to resync the domain with the server backends.
This can be used to force the server backend to refresh its copy of the domain without needing to make any changes.
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
This will always show a successful response, it only fires the sync hook.
Headers
Content-Type: application/json
Body
{
"respid": "58cef6194ca63",
"method": "domains/example.org/sync"
}
Scheduled domain verification ¶
Force backend syncGET/domains/{domain}/verify
Schedule a re-verification of the domain.
Example URI
- domain
string
(required) Example: example.orgThe domain name
200
This will always show a successful response, it only fires the verification hook.
Headers
Content-Type: application/json
Body
{
"respid": "637c6e5bae81a",
"method": "domains/example.org/verify"
}
ACME Requests - HTTPREQ / ACMEPROXY ¶
Endpoints for supporting HTTPREQ based ACME requests, as supported by lego and acme.sh (as acmeproxy)
Publish Records ¶
Present new ACME ChallengePOST/external/httpreq/present
If the user has the domains_write
permission, they can use this to submit the records for a new challenge.
We support normal mode or raw mode for this, and in raw mode we will accept the keyAuth
with the token prepended already or not.
In raw mode, we will calculate the desired fqdn
(_acme-challenge.<domain>
) and value
(base64(sha256(<token>.<keyAuth>))
) based on the provided domain
and token
+ keyAuth
parameters, then proceed as per normal mode.
This will then delete any TXT
records on the domain that match both the fqdn
and the given value
(or all if value
is blank) and then create a new one with the new value (unless value
is blank)
Example URI
Normal Mode
Headers
Content-Type: application/json
Body
{
"fqdn": "_acme-challenge.example1.org",
"value": "LHDhK3oGRvkiefQnx7OOczTY5Tic_xZ6HcMOc_gmtoM"
}
Raw Mode
Headers
Content-Type: application/json
Body
{
"domain": "example1.org",
"token": "ftSaeX_y0adqp2Q7RQwpTKtzUumMb-JoMVWyNLWUwyM",
"keyAuth": "ftSaeX_y0adqp2Q7RQwpTKtzUumMb-JoMVWyNLWUwyM.dO1Pl622P384UR9DFQ1wJLxfUfoldDh4nsedCZtnbdc"
}
200
A successful response will display any created/removed records
Headers
Content-Type: application/json
Body
{
"respid": "616b6577cfbb5",
"method": "httpreq/present",
"response": {
"serial": 2021101601,
"changed": [
{
"id": 705,
"content": "LHDhK3oGRvkiefQnx7OOczTY5Tic_xZ6HcMOc_gmtoM",
"deleted": true
},
{
"id": 706,
"remote_domain_id": null,
"name": "_acme-challenge.example1.org",
"type": "TXT",
"content": "LHDhK3oGRvkiefQnx7OOczTY5Tic_xZ6HcMOc_gmtoM",
"ttl": 60,
"priority": null,
"changed_at": 1634428279,
"changed_by": 1,
"disabled": false,
"updated": true
}
]
}
}
400
An error will include an error
and possibly errorData
information.
Headers
Content-Type: application/json
Body
{
"respid": "616b650485610",
"method": "httpreq/present",
"error": "No matching domains found for: _acme-challenge.example1.org"
}
Cleanup Records ¶
Cleanup ACME ChallengePOST/external/httpreq/cleanup
This behaves exactly the same (and takes exactly the same parameters) as /external/httpreq/present
but stops after clearing up the records and does not go on to create new ones.
Example URI
Normal Mode
Headers
Content-Type: application/json
Body
{
"fqdn": "_acme-challenge.example1.org",
"value": "LHDhK3oGRvkiefQnx7OOczTY5Tic_xZ6HcMOc_gmtoM"
}
Raw Mode
Headers
Content-Type: application/json
Body
{
"domain": "example1.org",
"token": "ftSaeX_y0adqp2Q7RQwpTKtzUumMb-JoMVWyNLWUwyM",
"keyAuth": "ftSaeX_y0adqp2Q7RQwpTKtzUumMb-JoMVWyNLWUwyM.dO1Pl622P384UR9DFQ1wJLxfUfoldDh4nsedCZtnbdc"
}
200
A successful response will display any created/removed records
Headers
Content-Type: application/json
Body
{
"respid": "616b6577cfbb5",
"method": "httpreq/cleanup",
"response": {
"serial": 2021101601,
"changed": [
{
"id": 705,
"content": "LHDhK3oGRvkiefQnx7OOczTY5Tic_xZ6HcMOc_gmtoM",
"deleted": true
}
]
}
}
400
An error will include an error
and possibly errorData
information.
Headers
Content-Type: application/json
Body
{
"respid": "616b650485610",
"method": "httpreq/present",
"error": "No matching domains found for: _acme-challenge.example1.org"
}
Domains Admin ¶
Admin Endpoints for dealing with domains, end points under /admin
require the manage_domains
permission.
As a general rule, anything that exists under /domains
also exists under /admin/domains
but in a less-restricted fashion. (ie, behaves as if the user had owner
access to all domains and allows setting the domain owner access level on a domain).
As such, to prevent documentation duplication, this section only lists methods where the result is different.
Get domains ¶
Get list of all known domainsGET/admin/domains
See what domains exist and user access levels for each.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "58bdf3b15c33b",
"method": "admin/domains",
"response":{
"example.org":{
"disabled": "false",
"users":{
"admin@example.org": "owner"
}
},
"test2.com":{
"disabled": "false",
"users":{
"admin@example.org": "owner"
}
},
"test3.com":{
"disabled": "false",
"users":{
"admin@example.org": "owner"
}
},
"test4.com":{
"disabled": "false",
"users":{
"admin@example.org": "owner"
}
},
"test5.com":{
"disabled": "false",
"users":{
"admin@example.org": "owner"
}
},
"example1.org":{
"disabled": "false",
"users":{
"user1@example.org": "owner"
}
},
"example2.org":{
"disabled": "false",
"users":{
"admin@example.org": "write",
"user2@example.org": "owner"
}
},
"example3.org":{
"disabled": "false",
"users":{
"user3@example.org": "owner"
}
},
"example4.org":{
"disabled": "false",
"users":{
"admin@example.org": "write",
"user4@example.org": "owner"
}
},
"example5.org":{
"disabled": "false",
"users":{
"user5@example.org": "owner"
}
},
"unowned1.com":{
"disabled": "false",
"users":{
"admin@example.org": "owner"
}
},
"unowned2.com":{
"disabled": "false",
"users":{
"admin@example.org": "read"
}
},
"unowned3.com":{
"disabled": "false",
"users":{
null
}
},
"unowned4.com":{
"disabled": "false",
"users":{
"admin@example.org": "read"
}
},
"unowned5.com":{
"disabled": "false",
"users":{
null
}
}
}
}
Create a new domainPOST/admin/domains
This behaves the same as the non-admin end-point, and requires the domains_create
permission in addition to the manage_domains
permission.
The admin version of the endpoint however also allows specifying an owner of a newly created domain.
If owner is not specified, then the current user will be set as the owner (same as non-admin end-point)
If owner is blank, no owner will be set.
Example URI
Create a domain
Headers
Content-Type: application/json
Body
{
"data": {
"domain": "example.net",
"owner": "someone@example.net"
}
}
200
A successful response will display the newly-created domain.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc0c377913",
"method": "domains",
"response": {
"id": "9",
"domain": "example.net",
"disabled": false,
"SOA": {
"primaryNS": "ns1.example.net.",
"adminAddress": "dnsadmin.example.net.",
"serial": "0",
"refresh": "86400",
"retry": "7200",
"expire": "2419200",
"minttl": "60"
}
}
}
400
An error will include an error
and possibly errorData
information.
Headers
Content-Type: application/json
Body
{
"respid": "58bcc115b3601",
"method": "domains",
"error": "Error updating domain.",
"errorData": "Duplicate entry 'example.net' for key 'domain_domain_unique'"
}
Articles ¶
Endpoints for dealing with articles.
These are used to display information to users after logging in.
Articles ¶
Get articlesGET/articles
This lets you get the current articles for display.
All articles will have “title”, “content” and “created” parameters. Some articles may include “contentfull” for additional content that can be displayed when viewing that specific article.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "5be8f02eaa91d",
"method": "articles",
"response": {
"1": {
"title": "2017-09-10 - Domain Statistics.",
"content": "Domain query statistics are now available from the API and from the zone details section.",
"created": "1505077534"
},
"2": {
"title": "2017-09-13 - DNSSEC Support is now live.",
"content": "Zones are automatically signed, with DS records available in the zone details section.",
"created": "1505259296"
},
"3": {
"title": "2017-09-24 - Domain display default page.",
"content": "A new setting has been added to the user-profile to change the default page displayed when viewing a domain to be either the \"Records\" or \"Zone Details\" page.",
"created": "1506219150"
},
"4": {
"title": "2017-11-26 - Domain Hooks, 2FA Changes, CNAME Validation.",
"content": "Support has now been added for Domain Hooks which get called whenever records on a domain are changed. There has also been some minor changes to the 2FA login flow (2FA Code is now requested on a separate page, and devices can be saved to bypass the 2FA requirement in future), and CNAME-and-other-records validation has been added.",
"created": "1511721570"
}
}
}
Articles Admin ¶
Get all articlesGET/admin/articles
This is similar to /articles
but will allow a user with the manage_articles
permission to show all the articles not just those that are visible.
All articles will have “title”, “content” and “created” parameters. Some articles may include “contentfull” for additional content that can be displayed when viewing that specific article.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid": "5be8f02eaa91d",
"method": "/admin/articles",
"response": {
"1": {
"id": "1",
"title": "2017-09-10 - Domain Statistics.",
"content": "Domain query statistics are now available from the API and from the zone details section.",
"contentfull": null,
"created": "1505077534",
"visiblefrom": "1505077534",
"visibleuntil": "-1"
},
"2": {
"id": "2",
"title": "2017-09-13 - DNSSEC Support is now live.",
"content": "Zones are automatically signed, with DS records available in the zone details section.",
"contentfull": null,
"created": "1505259296",
"visiblefrom": "1505259296",
"visibleuntil": "-1"
},
"3": {
"id": "3",
"title": "2017-09-24 - Domain display default page.",
"content": "A new setting has been added to the user-profile to change the default page displayed when viewing a domain to be either the \"Records\" or \"Zone Details\" page.",
"contentfull": null,
"created": "1506219150",
"visiblefrom": "1506219150",
"visibleuntil": "-1"
},
"4": {
"id": "4",
"title": "2017-11-26 - Domain Hooks, 2FA Changes, CNAME Validation.",
"content": "Support has now been added for Domain Hooks which get called whenever records on a domain are changed. There has also been some minor changes to the 2FA login flow (2FA Code is now requested on a separate page, and devices can be saved to bypass the 2FA requirement in future), and CNAME-and-other-records validation has been added.",
"contentfull": null,
"created": "1511721570",
"visiblefrom": "1511721570",
"visibleuntil": "-1"
}
}
}
Create an articlePOST/admin/articles
This allows a user with the manage_articles
permission to create new articles.
This behaves similarly to updating an article, except that “title”, “content”, “visiblefrom” and “visibleuntil” are all required.
Example URI
Create article
Headers
Content-Type: application/json
Body
{
"data": {
"title": "Test Article",
"content": "Some content",
"visiblefrom": 0,
"visibleuntil": -1
}
}
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcba77c1505",
"method": "admin/articles",
"response": {
"id": "5",
"title": "Test Article",
"content": "Some content",
"contentfull": null,
"created": 1552237749,
"visiblefrom": 0,
"visibleuntil": -1,
"updated": true
}
}
Manipulate Articles ¶
Get information about a specific articleGET/admin/articles/{articleid}
Returns complete information about the requested article.
Example URI
- articleid
string
(required) Example: 3The article ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcba77c1505",
"method": "admin/articles/3",
"response": {
"id": "3",
"title": "2017-09-24 - Domain display default page.",
"content": "A new setting has been added to the user-profile to change the default page displayed when viewing a domain to be either the \"Records\" or \"Zone Details\" page.",
"contentfull": null,
"created": "1506219150",
"visiblefrom": "1506219150",
"visibleuntil": "-1"
}
}
Update information about a specific articlePOST/admin/articles/{articleid}
Allows updating a specific article. Any fields that are passed in will be updated, fields not passed will be unchanged.
Example URI
- articleid
string
(required) Example: 3The article ID.
Change article data
Headers
Content-Type: application/json
Body
{
"data": {
"contentfull": "Additional content here."
}
}
200
The response on success will show the user account as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "58bcbc34234e3",
"method": "admin/articles/3",
"response": {
"id": "3",
"title": "2017-09-24 - Domain display default page.",
"content": "A new setting has been added to the user-profile to change the default page displayed when viewing a domain to be either the \"Records\" or \"Zone Details\" page.",
"contentfull": "Additional content here.",
"created": "1506219150",
"visiblefrom": "1506219150",
"visibleuntil": "-1",
"updated": true
}
}
400
If there is an error you will get an error
key rather than a response
key in the output
Headers
Content-Type: application/json
Body
{
"respid": "58bcbcc7dc8d1",
"method": "admin/articles/3",
"error": "Error updating artcile: 3"
}
Delete a specific ArticleDELETE/admin/articles/{articleid}
This will allow a user with the manage_articles
permission to delete the article specified.
Example URI
- articleid
string
(required) Example: 3The article ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcbde798d3a",
"method": "admin/articles/3",
"response": {
"deleted": "true"
}
}
BlockRegexes ¶
Endpoints for dealing with blockregexes.
These are used to block names/emails/domains that match a given regex.
BlockRegexes Admin ¶
Get all blockregexesGET/admin/blockregexes
This will allow a user with the manage_blocks
permission to see all the blockregexes.
Example URI
200
Headers
Content-Type: application/json
Body
{
"respid":"5be8f02eaa91d",
"method":"/admin/blockregexes",
"response":{
"1":{
"id": "1",
"regex": "/.*mydnshost\.co\.uk$/",
"comment": "Block attempts at pretending to be us",
"created": "1617430589",
"signup_email": true,
"signup_name": false,
"domain_name": true
}
}
}
Create an blockregexPOST/admin/blockregexes
This allows a user with the manage_blockregexes
permission to create new blockregexes.
This behaves similarly to updating an blockregex, except that “title”, “content”, “visiblefrom” and “visibleuntil” are all required.
Example URI
Create blockregex
Headers
Content-Type: application/json
Body
{
"data": {
"regex": "/.*mydnshost\.co\.uk$/",
"comment": "Block attempts at pretending to be us",
"signup_email": true,
"signup_name": false,
"domain_name": true
}
}
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcba77c1505",
"method": "admin/blockregexes",
"response":{
"id": "1",
"regex": "/.*mydnshost\.co\.uk$/",
"comment": "Block attempts at pretending to be us",
"created": "1617430589",
"signup_email": true,
"signup_name": false,
"domain_name": true
"updated": true
}
}
Manipulate BlockRegexes ¶
Get information about a specific blockregexGET/admin/blockregexes/{blockregexid}
Returns complete information about the requested blockregex.
Example URI
- blockregexid
string
(required) Example: 1The blockregex ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcba77c1505",
"method": "admin/blockregexes/1",
"response": {
"id": "1",
"regex": "/.*mydnshost\.co\.uk$/",
"comment": "Block attempts at pretending to be us",
"created": "1617430589",
"signup_email": true,
"signup_name": false,
"domain_name": true
}
}
Update information about a specific blockregexPOST/admin/blockregexes/{blockregexid}
Allows updating a specific blockregex. Any fields that are passed in will be updated, fields not passed will be unchanged.
Example URI
- blockregexid
string
(required) Example: 1The blockregex ID.
Change blockregex data
Headers
Content-Type: application/json
Body
{
"data": {
"comment": "Block people pretending to be us"
}
}
200
The response on success will show the user account as it exists after the change.
Headers
Content-Type: application/json
Body
{
"respid": "58bcbc34234e3",
"method": "admin/blockregexes/1",
"response":{
"id": "1",
"regex": "/.*mydnshost\.co\.uk$/",
"comment": "Block people pretending to be us"
"created": "1617430589",
"signup_email": true,
"signup_name": false,
"domain_name": true
"updated": true
}
}
400
If there is an error you will get an error
key rather than a response
key in the output
Headers
Content-Type: application/json
Body
{
"respid": "58bcbcc7dc8d1",
"method": "admin/blockregexes/1",
"error": "Error updating blockregex: 1"
}
Delete a specific BlockRegexDELETE/admin/blockregexes/{blockregexid}
This will allow a user with the manage_blockregexes
permission to delete the blockregex specified.
Example URI
- blockregexid
string
(required) Example: 1The blockregex ID.
200
Headers
Content-Type: application/json
Body
{
"respid": "58bcbde798d3a",
"method": "admin/blockregexes/1",
"response": {
"deleted": "true"
}
}
System ¶
Endpoints for dealing with system internals.
Whilst every effort will be made to keep the API stable, resources available under this endpoint are subject to change without warning as required.
System Information ¶
Get system datavalues from the APIGET/system/datavalue/{datavalue}
This lets you get system datavalues from the api. These are mostly used by the frontend to allow it to dynamically adapt to certain backend changes.
Some datavalues require authentication, some do not.
Example URI
- datavalue
string
(required) Example: validPermissionsThe datavalue to get.
200
Headers
Content-Type: application/json
Body
{
"respid": "59b5f1440fca4",
"method": "system/datavalue/validPermissions",
"response": {
"validPermissions": [
"domains_stats",
"manage_domains",
"domains_create",
"manage_users",
"manage_permissions",
"impersonate_users"
]
}
}
System Statistics ¶
Get system statistics from the APIGET/system/stats/{stat}{?type}
This lets you get system-level statistics from the api.
Example URI
- stat
string
(required) Example: queries-per-serverThe statistic to get (queries-per-server, queries-per-rrtype, queries-per-zone).
- type
string
(optional) Example: rawType of stats (raw or derivative)
200
Headers
Content-Type: application/json
Body
{
"respid": "59b5faf590931",
"method": "system/stats/queries-per-server",
"response":{
"stats":{
"ns1":[
{"time": 1505094900, "value": 18},
{"time": 1505094960, "value": 26},
{"time": 1505095020, "value": 28},
// More Stats
{"time": 1505098380, "value": 23},
{"time": 1505098440, "value": 8}
],
// More Servers
"ns4":[
{"time": 1505094900, "value": 14},
{"time": 1505094960, "value": 18},
{"time": 1505095020, "value": 28},
// More Stats
{"time": 1505098380, "value": 28},
{"time": 1505098440, "value": 6}
]
}
Custom Extensions ¶
In addition to standard DNS features, MyDNSHost also supports some custom record types, their behaviour is defined below.
Template Records
Record names prefixed with a $
(such as $server1
) are considered to be template records.
They will not be exported into the public zone file but are otherwise validated as normal.
They are primarily intended for use with RRCLONE
records.
RRCLONE
RRCLONE
records are special records that are replaced at zone-compile time with all active (not disabled) records matching the target provided (eg $server1.example.com
).
By default, all rrtypes are inserted, but this behaviour can be changed by adding a rrtype specifier to the start of the target, for example: (A,AAAA) $server1.example.com
will only insert A
and AAAA
records from $server1.example.com
RRCLONE
records can point at any other non-RRCLONE
record, and are not limited to just template records. If pointed at a template record from another zone file, the 2 zone files must both have a matching set of owner/admin/write users. This check can be passed by naming the record with $public-
rather than just $
to allow any user to reference it. Non-Template records are considered to be public records and can be referenced as such without a matching set of users.
Experimental ¶
There may be some experimental endpoints available under /experimental from time to time, these are mostly undocumented and should not be relied on.
You can find more information about some of these at https://api.mydnshost.co.uk/experimental/docs/