Parcourir la documentation

Gérer vos services

Toutes les routes de cette page prennent le code du service (SRV-TJUAQ1-1951), donné par GET /services. Un service hors de la restriction de la clé répond 404 SERVICE_NOT_FOUND.

GET /services

Permissions : services:read

ParamètreTypeRequisValeurs
limitentiernon, défaut 201 à 100
cursorstringnonpagination.nextCursor de la page précédente
statusstringnonACTIVE, SUSPENDED, CANCELLED, DELETED
curl -H "Authorization: Bearer $FRESHPERF_KEY" \
     "https://api.freshperf.fr/v1/services?limit=2&status=ACTIVE"
{
  "data": [
    {
      "code": "SRV-TJUAQ1-1951",
      "name": "Minecraft 1",
      "customName": null,
      "productShortname": "minecraft-1",
      "productTitle": "Minecraft 1",
      "category": "minecraft",
      "status": "ACTIVE",
      "providerType": "pterodactyl",
      "autoRenew": true,
      "nextBillingAt": 1789437385056,
      "recurrence": "monthly",
      "createdAt": 1786845385066,
      "activatedAt": 1786845385056
    }
  ],
  "pagination": { "nextCursor": null, "limit": 2 }
}
ChampTypeNotes
codestringl'identifiant de toutes les routes de service
namestringle nom personnalisé s'il existe, sinon le titre du produit
customNamestring ou nullle nom que vous avez donné
productShortnamestringà repasser en product dans une commande
productTitlestring ou nulllibellé du produit
categorystring ou nullshortname de la catégorie, ex. vps, minecraft
statusstringACTIVE, SUSPENDED, CANCELLED, DELETED
providerTypestring ou nullvps ou pterodactyl
autoRenewbooléen
nextBillingAtentier ou nullmillisecondes epoch
recurrencestring ou nullcycle de facturation, ex. monthly
createdAt, activatedAtentier ou nullmillisecondes epoch

GET /services/{code}

Permissions : services:read

Reprend les champs ci-dessus et ajoute :

ChampTypeNotes
provisionedbooléenfalse tant que l'infrastructure n'existe pas
priceCentsentierprix récurrent d'un cycle, hors taxe
taxCentsentiertaxe du même cycle
currencystring ou nullISO 4217
dunningStatestringNONE, RETRY, SUSPENSION_TRIGGERED, DELETION_TRIGGERED
restartRequiredbooléenun changement de ressources attend un redémarrage
restartRequiredReasonstring ou null
configurationobjet string → stringla configuration commandée. Les identifiants de connexion et les clés internes en sont retirés
cancelledAtentier ou nullmillisecondes epoch
{
  "data": {
    "code": "SRV-TIYMZT-8349",
    "name": "VPS 1",
    "status": "ACTIVE",
    "providerType": "vps",
    "provisioned": true,
    "autoRenew": true,
    "nextBillingAt": 1787960297645,
    "recurrence": "monthly",
    "priceCents": 500,
    "taxCents": 100,
    "currency": "EUR",
    "dunningState": "NONE",
    "restartRequired": false,
    "restartRequiredReason": null,
    "configuration": {
      "os": "debian", "osVersion": "13", "location": "paris",
      "cpuCores": "2", "ramSize": "2048", "diskSize": "20"
    },
    "cancelledAt": null
  }
}

GET /services/{code}/status

Permissions : services.metrics:read

Interroge l'infrastructure en direct. Comptez jusqu'à deux secondes de latence.

Tous les champs peuvent valoir null : chaque fournisseur remonte ce qu'il connaît.

ChampTypeNotes
statusstringtexte du fournisseur : running, stopped, starting, stopping, restoring... Ce n'est pas une énumération fermée
uptimeSecondsentier
cpunombrefraction ou pourcentage selon le fournisseur
cpuCountnombre
memoryBytes, memoryMaxBytesentieroctets
diskBytes, diskMaxBytesentieroctets
networkInBytes, networkOutBytesentieroctets
ipv4stringpour un serveur de jeu, adresse:port
ipv6string
extraIpv4tableau de stringadresses supplémentaires
hostnamestring
extraobjetles chiffres propres au fournisseur. Contenu libre, non versionné

INSTANCE_NOT_PROVISIONED (409) tant que l'infrastructure n'existe pas.

GET /services/{code}/metrics/history

Permissions : services.metrics:read

{ "data": { "samples": [
  { "ts": 1787903520000, "cpu": 0.1364, "mem": 1069400678, "maxmem": 2147483648, "netin": 4550, "netout": 69 }
] } }

samples est un tableau d'objets libres : la fenêtre, le pas et les clés viennent du fournisseur. Le tableau est vide quand aucun historique n'est disponible, notamment sur les serveurs de jeu.

POST /services/{code}/power

Permissions : services.power:write Débit : 20 par minute, par clé et par service.

ChampTypeRequisValeurs
actionstringouistart, stop, restart, kill

kill n'existe que sur les serveurs de jeu ; sur un VPS il répond 400 ACTION_UNSUPPORTED.

curl -X POST -H "Authorization: Bearer $FRESHPERF_KEY" \
     -H "Content-Type: application/json" -d '{"action":"restart"}' \
     https://api.freshperf.fr/v1/services/SRV-TJUAQ1-1951/power
{ "data": { "status": "SUCCESS", "message": "Power signal accepted" } }
ChampValeurs
statusSUCCESS quand c'est fait, PENDING quand l'infrastructure y travaille encore
messagephrase du fournisseur, ou null

Sur PENDING, relisez /status toutes les 5 à 10 secondes.

ErreurStatutQuand
VALIDATION_ERROR:action400action absent ou hors liste
ACTION_UNSUPPORTED400kill sur un VPS
SERVICE_NOT_ACTIVE409service suspendu ou résilié
INSTANCE_NOT_PROVISIONED409pas encore d'infrastructure

POST /services/{code}/console/command

Permissions : services.console:write

Serveurs de jeu uniquement.

ChampTypeRequis
commandstringoui, non vide
curl -X POST -H "Authorization: Bearer $FRESHPERF_KEY" \
     -H "Content-Type: application/json" -d '{"command":"say bonjour"}' \
     https://api.freshperf.fr/v1/services/SRV-TJUAQ1-1951/console/command
{ "data": { "status": "SUCCESS", "message": "Command sent" } }

Sur un VPS : 400 ACTION_UNSUPPORTED. Sur un serveur arrêté, le panneau refuse la commande et la réponse est 502 ACTION_FAILED.

Sauvegardes

Les quatre routes relaient le fournisseur. La réponse a toujours la même forme : {"data": {"status", "message", "result"}}, où result est la charge utile du fournisseur.

GET /services/{code}/backups

Permissions : services.backups:read

Répond même sur un service suspendu.

{ "data": { "status": "SUCCESS", "message": "OK", "result": {
  "customerEnabled": true,
  "limits": { "max": 6, "used": 2 },
  "customer": [
    { "id": "9b5d3938-cbd9-4946-8357-05badcdf6c33",
      "note": null, "status": "COMPLETED",
      "createdAt": "2026-08-15T19:50:45.282411", "sizeBytes": 21474837581 }
  ],
  "internal": []
} } }

Le id d'une sauvegarde est une chaîne, propre au fournisseur. C'est ce que prennent la suppression et la restauration.

POST /services/{code}/backups

Permissions : services.backups:write

ChampTypeRequisValeurs
notestring ou nullnon200 caractères au plus
{ "data": { "status": "PENDING", "message": "VPS backup in progress",
  "result": { "taskId": "d3b780a2-308f-40bf-95a2-0316d8872721", "status": "PENDING" } } }
ErreurStatutQuand
NOTE_TOO_LONG400note au-delà de 200 caractères
SERVICE_NOT_ACTIVE400service suspendu ou résilié
SERVICE_IN_DUNNING400service en recouvrement
INSTANCE_NOT_PROVISIONED400pas encore d'infrastructure
LIMIT_REACHED409quota de sauvegardes atteint
BACKUP_IN_PROGRESS400une sauvegarde ou une restauration tourne déjà

DELETE /services/{code}/backups/{backupId}

Permissions : services.backups:write

backupId vient de result.customer[].id. Un identifiant inconnu répond 400 BACKUP_NOT_FOUND.

POST /services/{code}/backups/restore

Permissions : services.backups:write

Écrase le disque.

ChampTypeRequisValeursD'où il vient
sourcestringouiCUSTOMER ou INTERNAL-
backupIdstringoui si source vaut CUSTOMER-result.customer[].id
volidstringoui si source vaut INTERNAL-result.internal[].volid

Mêmes refus que la création, plus 400 MISSING_FIELDS quand source est absent ou que l'identifiant qui va avec manque.

POST /services/{code}/reinstall

Permissions : services.reinstall:write Débit : 2 par minute, par clé et par service. Les appels refusés comptent.

Détruit le disque. Sur un serveur de jeu, remet le serveur à zéro et le corps peut être vide.

ChampTypeRequisValeursD'où il vient
osstringoui sur un VPSvaleur composite <famille>-<version>GET /catalog/products/{shortname} → caractéristique de kind: "os-picker", champ options
authTypestringoui sur un VPSPASSWORD ou SSH_KEY-
authValuestringoui sur un VPSle mot de passe, ou une ligne de clé publique OpenSSH-

authValue est stocké chiffré, n'est jamais renvoyé, et cet appel n'est jamais journalisé avec son corps.

curl -X POST -H "Authorization: Bearer $FRESHPERF_KEY" \
     -H "Content-Type: application/json" \
     -d '{"os":"debian-13","authType":"SSH_KEY","authValue":"ssh-ed25519 AAAAC3Nza... admin@laptop"}' \
     https://api.freshperf.fr/v1/services/SRV-TIYMZT-8349/reinstall
{ "data": { "status": "PENDING", "message": "reinstalling" } }
ErreurStatutQuand
MISSING_FIELDS400un des trois champs manque sur un VPS
INVALID_OS400os hors des valeurs du catalogue
OS_FAMILY_MISMATCH400famille et version incompatibles
INVALID_AUTH_TYPE400authType hors liste
SERVICE_NOT_ACTIVE, SERVICE_IN_DUNNING, INSTANCE_NOT_PROVISIONED400état du service
API_RATE_LIMITED429plus de 2 appels dans la minute

GET /services/{code}/addons

Permissions : services.addons:read

{ "data": {
  "addons": [
    { "shortname": "extra-saves", "title": "Sauvegardes supplémentaires",
      "kind": "BACKUP_SLOTS", "status": "ACTIVE", "quantity": 1,
      "unitPriceCents": 399, "unitTaxCents": 80,
      "linePriceCents": 399, "lineTaxCents": 80,
      "nextCycleLinePriceCents": 399, "nextCycleLineTaxCents": 80,
      "pendingRemovalQuantity": 0 }
  ],
  "available": [
    { "shortname": "extra-ram-1gb", "title": { "fr-fr": "+1 Go RAM", "en-us": "+1 Gb RAM" },
      "kind": "RESOURCE_DELTA", "resourceKey": "ramSize", "unitDelta": 1024,
      "unitPriceCents": 200, "maxQuantity": 10 }
  ],
  "recurringTotalCents": 479
} }
ChampContenu
addonsles options que le service porte déjà
availablecelles qu'il peut encore prendre. maxQuantity à 0 veut dire sans limite
recurringTotalCentsle total récurrent du service, options comprises, hors taxe

Ajouter ou retirer une option se fait dans le tableau de bord.

PATCH /services/{code}

Permissions : services:write

ChampTypeRequisValeurs
customNamestring ou nullnon32 caractères au plus. La chaîne vide efface le nom
autoRenewbooléennontrue uniquement
curl -X PATCH -H "Authorization: Bearer $FRESHPERF_KEY" \
     -H "Content-Type: application/json" -d '{"customName":"prod-eu-1"}' \
     https://api.freshperf.fr/v1/services/SRV-TJUAQ1-1951

Répond le service complet, comme GET /services/{code}.

ErreurStatutQuand
CUSTOM_NAME_TOO_LONG400au-delà de 32 caractères
RENEWAL_CANCELLATION_NOT_AVAILABLE_VIA_API400autoRenew: false. Arrêter un renouvellement se fait dans le tableau de bord

POST /services/{code}/renew

Permissions : services:write et billing.invoices:pay, plus billing.saved_methods:charge dès que le financement touche une carte. En-tête obligatoire : Idempotency-Key.

Débite le cycle suivant tout de suite et avance la date de facturation.

ChampTypeRequisValeursD'où il vient
methodstringnon, défaut account_defaultaccount_default, balance, saved_method-
paymentMethodIdentieroui si saved_method> 0GET /payment-methodsid
methodEffet
account_defaultapplique la règle du compte : le solde s'il est opté et suffisant, sinon le moyen de paiement par défaut. Le passage par la carte exige billing.saved_methods:charge
balancele solde prépayé seul. Aucun repli sur une carte
saved_methoddébite le moyen désigné
curl -X POST -H "Authorization: Bearer $FRESHPERF_KEY" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: renew-SRV-TJUAQ1-1951-2026-08" \
     -d '{"method":"balance"}' \
     https://api.freshperf.fr/v1/services/SRV-TJUAQ1-1951/renew
{ "data": { "status": "CHARGED", "serviceCode": "SRV-TJUAQ1-1951",
            "nextBillingAt": 1793091315189, "amountCents": 360 } }

status ne vaut que CHARGED : toute autre issue est une erreur. amountCents est le montant débité, taxe comprise.

ErreurStatutQuand
VALIDATION_ERROR:method400method hors liste
PAYMENT_METHOD_ID_REQUIRED400saved_method sans paymentMethodId
PAYMENT_METHOD_NOT_FOUND404ce moyen n'est pas sur le compte
INSUFFICIENT_BALANCE402solde trop court
NO_PAYMENT_METHOD402account_default sans moyen utilisable
PAYMENT_METHOD_NOT_ACTIVE402moyen expiré ou bloqué
RENEWAL_FAILED402le débit a échoué pour une autre raison
API_KEY_SPENDING_CAP_EXCEEDED403le plafond de la clé ne couvre pas le cycle
SERVICE_NOT_ACTIVE409service ni actif ni réactivable
RENEWAL_IN_PROGRESS409un renouvellement du même service tourne déjà
RENEWAL_TOO_FREQUENT429moins d'une minute depuis le précédent

POST /services/{code}/actions/{action}

Permissions : elles dépendent de l'action envoyée.

La passerelle brute vers le fournisseur. Elle sert au pare-feu et au DNS inverse, qui n'ont pas de route dédiée.

ActionPermission
power, start_vps, stop_vps, reboot_vpsservices.power:write
send_console_commandservices.console:write
backup_listservices.backups:read
backup_create, backup_delete, backup_restoreservices.backups:write
firewall_listservices.firewall:read
firewall_create, firewall_update, firewall_move, firewall_deleteservices.firewall:write
rdnsservices.rdns:write, y compris pour op: "get"
featuresservices:read

Aucune autre action n'est joignable. Il n'existe pas de firewall_add, firewall_set ni firewall_remove : une règle se crée, se modifie et se supprime avec firewall_create, firewall_update et firewall_delete.

Les actions de panneau de jeu (files, databases, allocations, schedules, startup, versions, content, subdomains, sftp, subusers) répondent 403 API_ACTION_NOT_ALLOWED quelles que soient les permissions de la clé.

ChampTypeRequis
argumentsobjetnon. Contenu propre à chaque action
curl -X POST -H "Authorization: Bearer $FRESHPERF_KEY" \
     -H "Content-Type: application/json" \
     -d '{"arguments":{"op":"set","address":"203.0.113.224","hostname":"vps.exemple.fr"}}' \
     https://api.freshperf.fr/v1/services/SRV-TIYMZT-8349/actions/rdns
{ "data": { "status": "SUCCESS", "message": "Action completed", "result": {
  "configured": true,
  "entries": [
    { "family": "ipv4", "address": "203.0.113.224", "hostname": "vps.exemple.fr", "zoneConfigured": true }
  ]
} } }

rdns prend op valant get, set ou delete, plus address (une adresse rendue par /status) et, pour set, hostname. Les arguments des actions firewall_* dépendent de l'hyperviseur : lisez firewall_list pour voir la forme d'une règle avant d'en écrire une.

ErreurStatutQuand
INVALID_ACTION400action vide ou commençant par _
API_ACTION_NOT_ALLOWED:<action>403action inconnue de la plateforme, ou sans permission publique
SERVICE_NOT_ACTIVE409service suspendu ou résilié
marqueur du fournisseur, ex. FIREWALL_INVALID_ARGUMENT409le fournisseur a refusé
ACTION_FAILED502le fournisseur a échoué ou n'a pas répondu

Préférez les routes typées (/power, /backups, /reinstall, /console/command) partout où elles existent : elles sont stables et indépendantes du fournisseur.