Open platform for developers

freedns.my

My Free domain names



Open platform for developers

Third parties can sign a user in with Sign in with freedns.my and then read - or, with the write scope, change - what that user explicitly allowed. It is plain OAuth 2.0 (authorisation code), so any OAuth client library works. Start by submitting an application on /account/apps.php: a human approves it, and then you get a client_id (and, unless you registered a public client, a client_secret shown once).

Endpoints

EndpointWhat it does
GET /oauth/authorize.phpThe consent screen. Send the user here.
POST /oauth/token.phpExchange a code for tokens; refresh an expired access token.
GET /oauth/userinfo.phpWho the token belongs to. Scope: profile.
GET /open/v1/domains.phpThe names this account holds. Scope: domains.
GET /open/v1/records.php?name=…The DNS records of one name. Scope: records.
POST /open/v1/records.php?name=…Add a record. Scope: records.write.
PUT changes one by index=, DELETE removes one.
GET /open/v1/mailboxes.phpMailboxes and forwarding of this account. Scope: mailboxes.
GET /open/v1/applications.phpRequests, quota and counts. Scope: applications.

Every answer is JSON. Errors follow RFC 6749: {"error":"…","error_description":"…"}. A request with a missing, expired or revoked token is 401; a token without the scope the call needs is 403 insufficient_scope; a record the registry refuses is 422 with the same sentence the web console would have shown.

Scopes

ScopeGrants
profileAccount basics (username, e-mail, whether it is confirmed)
domainsYour names (name, state, suffix, registered date)
recordsRead the DNS records of your names
records.writeChange the DNS records of your names
mailboxesYour mailboxes on this registry (address, state, quota)
applicationsYour requests, their progress, your quota and counts

The user sees these sentences on the consent screen and may refuse any application. An application can only ask for scopes the operator approved for it; anything else is refused with invalid_scope.

Quick start (curl)

# 0) PKCE pair. Keep the verifier; send the challenge. (openssl, or any library)
VERIFIER=$(openssl rand -hex 32)
CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -binary -sha256 | openssl base64 | tr '+/' '-_' | tr -d '=')

# 1) Send the user to the consent screen (in a browser, while they are signed in):
#      https://freedns.my/ja/oauth/authorize.php?response_type=code
#        &client_id=YOUR_CLIENT_ID
#        &redirect_uri=https%3A%2F%2Fyour.app%2Fcallback
#        &scope=profile%20domains%20records
#        &state=RANDOM
#        &code_challenge=$CHALLENGE&code_challenge_method=S256
#
#    They press Allow, and your callback receives: ?code=…&state=RANDOM

# 2) Exchange the code for tokens (10 minutes, one use only):
curl -s -X POST https://freedns.my/ja/oauth/token.php \
  -d grant_type=authorization_code \
  -d client_id=YOUR_CLIENT_ID -d client_secret=YOUR_SECRET \
  -d redirect_uri=https://your.app/callback \
  -d code=THE_CODE -d code_verifier="$VERIFIER"
# => {"access_token":"…","token_type":"Bearer","expires_in":3600,"refresh_token":"…","scope":"profile domains records"}

# 3) Use it:
curl -s -H "Authorization: Bearer $ACCESS" https://freedns.my/ja/oauth/userinfo.phpcurl -s -H "Authorization: Bearer $ACCESS" https://freedns.my/ja/open/v1/domains.phpcurl -s -H "Authorization: Bearer $ACCESS" "https://freedns.my/ja/open/v1/records.php?name=abc.us.ci"

# 4) Change a record (needs records.write):
curl -s -X POST -H "Authorization: Bearer $ACCESS" \
  -d "sub=www" -d "type=A" -d "value=1.2.3.4" \
  "https://freedns.my/ja/open/v1/records.php?name=abc.us.ci"

# 5) When the access token expires, refresh it. The old refresh token dies at this moment:
curl -s -X POST https://freedns.my/ja/oauth/token.php \
  -d grant_type=refresh_token -d client_id=YOUR_CLIENT_ID -d client_secret=YOUR_SECRET \
  -d refresh_token=$REFRESH

PHP, without a library

$ch = curl_init('https://freedns.my/ja/open/v1/domains.php');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $accessToken],
]);
$answer = json_decode((string)curl_exec($ch), true);
if (($answer['ok'] ?? false) !== true) {
    // $answer['error'] is machine readable, $answer['message'] or ['error_description'] is for a human
}

Rules that will not change

Everything else

Submit and manage applications on /account/apps.php (holders see who is connected to them there, and can disconnect). The API for a single key that acts as the account itself lives on /account/api.php. The open platform is switched off as a whole while the tables are missing; a call then answers 503 temporarily_unavailable.


freedns.my — 無料ドメインレジストリ。 連絡先: [email protected]. ページ生成時刻 2026-10-06 12:53(UTC)。