Aller au contenu principal

L'API des sous-domaines et des domaines

Kuploy fournit des sous-domaines *.kuploy.app gratuits pour vos applications, l'enregistrement de domaines personnalisés, et l'achat de domaines. Cette API permet aux instances kuploy-cloud de mettre en service et de gérer tout cela par programme.

Pour les exploitants

Cette documentation s'adresse aux exploitants qui intègrent la mise en service de sous-domaines à leurs instances kuploy-cloud. Les utilisateurs finaux manipulent d'ordinaire les sous-domaines depuis l'interface de l'application, et non directement par cette API.

Vue d'ensemble​

L'API des sous-domaines permet de :

  • vérifier la disponibilité d'un sous-domaine ;
  • réserver des sous-domaines pour une instance ;
  • mettre en service les enregistrements DNS ;
  • libérer un sous-domaine lorsqu'il n'est plus nécessaire.

L'API des domaines personnalisés permet de :

  • enregistrer des domaines personnalisés sur votre licence ;
  • retirer ces enregistrements ;
  • lister les domaines personnalisés d'une instance.

L'API des domaines achetés permet de :

  • enregistrer des domaines achetés chez un bureau d'enregistrement ;
  • retirer ces enregistrements ;
  • lister les domaines achetés d'une instance.

Tous les points d'accès exigent une authentification par votre clé de licence.

La configuration​

Votre instance kuploy-cloud doit avoir ces variables d'environnement définies :

VariableDescription
LICENSE_HUB_URLL'URL de base de l'instance kuploy-app (par exemple https://kuploy.app)
LICENSE_KEYVotre clé de licence, obtenue sur kuploy-app

L'URL de base​

L'API des sous-domaines est disponible sur :

{LICENSE_HUB_URL}/api/subdomain

Par exemple : https://kuploy.app/api/subdomain

L'authentification​

Toute requête doit comporter votre LICENSE_KEY, comme champ licenseKey du corps de la requête :

{
"licenseKey": "{LICENSE_KEY}",
...
}

Les points d'accès​

Vérifier la disponibilité​

Vérifie si un nom de sous-domaine est libre.

POST /api/subdomain/check

Requête :

{
"name": "my-app"
}

Réponse (disponible) :

{
"available": true,
"name": "my-app",
"fqdn": "my-app.kuploy.app"
}

Réponse (indisponible) :

{
"available": false,
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"error": "This subdomain is already taken"
}

Réserver un sous-domaine​

Réserve un sous-domaine pour une instance. Cela ne crée pas encore d'enregistrement DNS.

POST /api/subdomain/reserve

Requête :

{
"name": "my-app",
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"subdomain": {
"id": "sub_xxxxxxxxxxxxxxxx",
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"status": "pending"
}
}

Erreur (limite atteinte) :

{
"success": false,
"error": "Subdomain limit reached (5). Upgrade your plan for more subdomains."
}

Mettre en service l'enregistrement DNS​

Crée l'enregistrement DNS effectif d'un sous-domaine réservé.

POST /api/subdomain/provision

Requête :

{
"subdomainId": "sub_xxxxxxxxxxxxxxxx",
"ipAddress": "203.0.113.50",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"subdomain": {
"id": "sub_xxxxxxxxxxxxxxxx",
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"ipAddress": "203.0.113.50",
"status": "active"
}
}
astuce

La propagation DNS est d'ordinaire instantanée, Kuploy gérant le DNS autoritaire de kuploy.app.

Libérer un sous-domaine​

Libère un sous-domaine et supprime son enregistrement DNS.

POST /api/subdomain/release

Requête :

{
"subdomainId": "sub_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"message": "Subdomain my-app.kuploy.app has been released"
}

Lister les sous-domaines​

Liste tous les sous-domaines d'une instance.

POST /api/subdomain/list

Requête :

{
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"subdomains": [
{
"id": "sub_xxxxxxxxxxxxxxxx",
"name": "my-app",
"fqdn": "my-app.kuploy.app",
"ipAddress": "203.0.113.50",
"status": "active",
"provisionedAt": "2025-01-10T12:00:00Z",
"createdAt": "2025-01-10T11:55:00Z"
}
]
}

L'état d'un sous-domaine​

ÉtatDescription
pendingRéservé, mais le DNS n'est pas encore mis en service
activeL'enregistrement DNS est créé et actif
suspendedTemporairement désactivé
releasedAutrefois utilisé, désormais libre

Les règles de nommage des sous-domaines​

Un sous-domaine doit respecter ces règles :

  • Longueur : de 3 à 63 caractères
  • Caractères : uniquement des lettres minuscules, des chiffres et des traits d'union
  • Forme : ne peut ni commencer ni finir par un trait d'union
  • Unicité : doit être unique parmi tous les utilisateurs de Kuploy

Les noms réservés​

Les sous-domaines suivants sont réservés et ne peuvent pas être utilisés :

www, app, api, admin, mail, smtp, pop, imap, ftp, ssh,
ns1, ns2, dns, test, dev, staging, prod, production,
beta, alpha, status, help, support, docs, blog, cdn,
static, assets, media, images, img, dashboard, billing,
account, login, signup, register, auth, oauth, sso, kuploy

Les codes d'erreur​

Statut HTTPErreurDescription
400INVALID_SUBDOMAINLe nom ne respecte pas les règles de nommage
400INVALID_IPLe format de l'adresse IPv4 est invalide
403LIMIT_REACHEDLa limite de sous-domaines de l'offre est dépassée
404NOT_FOUNDLe sous-domaine ou l'instance est introuvable
409ALREADY_TAKENLe sous-domaine est déjà réservé par un autre utilisateur

Un exemple d'intégration​

Voici un enchaînement typique, pour mettre un sous-domaine en service :

const LICENSE_HUB_URL = process.env.LICENSE_HUB_URL;
const LICENSE_KEY = process.env.LICENSE_KEY;

// 1. Vérifier la disponibilité
const check = await fetch(`${LICENSE_HUB_URL}/api/subdomain/check`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'my-app' })
});
const { available } = await check.json();

if (!available) {
throw new Error('Subdomain not available');
}

// 2. Réserver le sous-domaine
const reserve = await fetch(`${LICENSE_HUB_URL}/api/subdomain/reserve`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'my-app',
instanceId: 'inst_xxx',
licenseKey: LICENSE_KEY
})
});
const { subdomain } = await reserve.json();

// 3. Mettre le DNS en service, une fois l'adresse IP connue
const provision = await fetch(`${LICENSE_HUB_URL}/api/subdomain/provision`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
subdomainId: subdomain.id,
ipAddress: '203.0.113.50',
licenseKey: LICENSE_KEY
})
});

// Le sous-domaine est désormais actif sur my-app.kuploy.app

Les limites de débit​

Les requêtes à l'API sont limitées en débit, licence par licence :

OpérationLimite
Vérifier la disponibilité60 par minute
Réserver, mettre en service, libérer10 par minute
Lister les sous-domaines30 par minute

Dépasser ces limites renvoie un HTTP 429, avec un en-tête Retry-After.

L'API des domaines personnalisés​

Les domaines personnalisés permettent à vos utilisateurs de rattacher leurs propres domaines — app.example.com, par exemple — à leurs applications. Ces points d'accès enregistrent et gèrent ces domaines auprès du centre de licences.

Une offre est requise

Les domaines personnalisés exigent une offre Starter ou supérieure. Une requête émise depuis l'offre Hobby renvoie une erreur 403.

L'URL de base​

{LICENSE_HUB_URL}/api/custom-domain

Enregistrer un domaine personnalisé​

Enregistre un domaine personnalisé pour une instance. Les interrupteurs de fonctionnalités et les limites de domaines de l'offre sont appliqués côté serveur.

POST /api/custom-domain/register

Requête :

{
"host": "app.example.com",
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse (succès) :

{
"success": true,
"customDomain": {
"id": "cd_xxxxxxxxxxxxxxxx",
"host": "app.example.com",
"status": "active"
}
}

Erreur (l'offre ne comprend pas les domaines personnalisés) :

{
"error": "Custom domains are not available on your plan. Upgrade to Starter or higher."
}

Erreur (limite atteinte) :

{
"error": "Custom domain limit reached (10). Upgrade your plan for more custom domains."
}

Retirer un domaine personnalisé​

Retire l'enregistrement d'un domaine personnalisé et libère une place.

POST /api/custom-domain/remove

Requête :

{
"customDomainId": "cd_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"message": "Custom domain app.example.com has been removed"
}

Lister les domaines personnalisés​

Liste tous les domaines personnalisés enregistrés pour une instance.

POST /api/custom-domain/list

Requête :

{
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"customDomains": [
{
"id": "cd_xxxxxxxxxxxxxxxx",
"host": "app.example.com",
"status": "active",
"createdAt": "2025-01-10T12:00:00Z"
}
]
}

Les codes d'erreur des domaines personnalisés​

Statut HTTPErreurDescription
400INVALID_HOSTLe format du domaine est invalide
403FEATURE_DISABLEDL'offre ne comprend pas les domaines personnalisés
403LIMIT_REACHEDLa limite de domaines personnalisés de l'offre est dépassée
403LICENSE_SUSPENDEDLa licence est suspendue

L'API des domaines achetés​

Les domaines achetés sont ceux acquis par l'intégration de la plateforme à un bureau d'enregistrement — Namecheap, par exemple. Ces points d'accès les font suivre par le centre de licences, pour l'application des limites d'offre.

Une offre est requise

L'achat de domaines exige que l'interrupteur domainPurchase soit activé — soit par votre licence de plateforme (Enterprise, par exemple), soit par l'offre souscrite par l'utilisateur (Pro ou Business, par exemple). Une requête dépourvue de cette fonctionnalité renvoie une erreur 403. L'instance kuploy-cloud applique une vérification licence d'abord, offre en recours avant d'appeler cette API. Voir Administrer les domaines — le contrôle d'accès pour le détail.

L'URL de base​

{LICENSE_HUB_URL}/api/purchased-domain

Enregistrer un domaine acheté​

Enregistre un domaine acquis chez le bureau d'enregistrement. L'interrupteur domainPurchase et la limite purchasableDomains sont appliqués côté serveur. L'appel est idempotent : réenregistrer le même hôte pour la même instance renvoie l'enregistrement existant.

POST /api/purchased-domain/register

Requête :

{
"host": "example.com",
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx",
"registrarId": "12345",
"expiresAt": "2027-01-15T00:00:00Z",
"autoRenew": true
}
ChampObligatoireDescription
hostOuiLe nom du domaine acheté
instanceIdOuiL'instance qui possède ce domaine
licenseKeyOuiLa clé de licence, pour l'autorisation
registrarIdNonL'identifiant du domaine chez le bureau d'enregistrement
expiresAtNonLa date d'expiration du domaine, au format ISO 8601
autoRenewNonL'activation du renouvellement automatique (par défaut : true)

Réponse (succès) :

{
"success": true,
"purchasedDomain": {
"id": "pd_xxxxxxxxxxxxxxxx",
"host": "example.com",
"status": "active"
}
}

Erreur (fonctionnalité indisponible) :

{
"success": false,
"error": "Domain purchasing is not available on your plan. Upgrade to a plan with domain purchase enabled."
}

Erreur (limite atteinte) :

{
"success": false,
"error": "Purchased domain limit reached (10). Upgrade your plan for more purchasable domains."
}

Retirer un domaine acheté​

Retire l'enregistrement d'un domaine acheté et libère une place. Cela ne résilie pas le domaine chez le bureau d'enregistrement : seul le suivi par le centre de licences disparaît.

POST /api/purchased-domain/remove

Requête :

{
"purchasedDomainId": "pd_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"message": "Purchased domain has been removed"
}

Lister les domaines achetés​

Liste tous les domaines achetés actifs d'une instance.

POST /api/purchased-domain/list

Requête :

{
"instanceId": "inst_xxxxxxxxxxxxxxxx",
"licenseKey": "lic_xxxxxxxxxxxxxxxx"
}

Réponse :

{
"success": true,
"purchasedDomains": [
{
"id": "pd_xxxxxxxxxxxxxxxx",
"host": "example.com",
"status": "active",
"registrarId": "12345",
"expiresAt": "2027-01-15T00:00:00Z",
"autoRenew": true,
"createdAt": "2026-01-15T12:00:00Z"
}
]
}

Les codes d'erreur des domaines achetés​

Statut HTTPErreurDescription
400MISSING_FIELDSDes champs obligatoires manquent dans la requête
403FEATURE_DISABLEDL'offre ne comprend pas l'achat de domaines
403LIMIT_REACHEDLa limite de domaines achetés de l'offre est dépassée
403LICENSE_SUSPENDEDLa licence est suspendue
404NOT_FOUNDLe domaine ou l'instance est introuvable