http api

Tout ce que fait le tableau de bord, depuis ton terminal

Une clé de compte. Liste tes sites, déploie dessus, renomme-les, lis ce que tes formulaires ont récolté, supprime-les — en HTTP tout simple, depuis un script, un job de CI ou un agent.

démarrage

Trois commandes

Crée une clé sur ton tableau de bord, vérifie qu'elle marche, et mets un dossier en ligne. La clé va dans un en-tête Authorization à chaque appel.

Vérifier que la clé marche
curl -H "Authorization: Bearer hvs_…" https://harvis.dev/api/v1
Voir ce qu'il y a sur le compte
curl -H "Authorization: Bearer hvs_…" https://harvis.dev/api/v1/sites
Publier un dossier
curl -X POST https://harvis.dev/api/v1/sites \
  -H "Authorization: Bearer hvs_…" \
  -F "files=@index.html" -F "paths=index.html"
un contrat

L'app web et l'API ne peuvent pas diverger

Chaque capacité est déclarée une fois, dans un seul fichier, et le tableau de bord comme cette API sont construits à partir de là. openapi.json est généré depuis cette déclaration, et le build échoue si les deux divergent. Ce n'est donc pas une documentation qui décrit le produit — c'est ce dont le produit est fait.

  • Une implémentation par capacité, appelée par l'app web comme par ton script.
  • openapi.json est généré, jamais écrit à la main, et servi sur /openapi.json.
  • Un build échoue dès qu'une route, le contrat et le document cessent de concorder.
déploiements

Avec une clé, le site est à toi immédiatement

Déployer sans compte marche toujours et marchera toujours — tu reçois un lien de revendication privé à ouvrir plus tard. Envoie une clé sur le même appel et il n'y a rien à revendiquer : le site est sur ton compte dès le premier octet, et il n'expire jamais.

zip -r site.zip . && curl -X POST https://harvis.dev/api/upload \
  -H "Authorization: Bearer hvs_…" \
  -H "Content-Type: application/zip" --data-binary @site.zip
endpoints

Toute la surface

Les formes complètes des requêtes et des réponses sont dans le document OpenAPI.

méthodechemince qu'il fait
GET/api/v1Check that a credential works.
GET/api/v1/keysThe account's API keys. Revoked keys are not listed.
POST/api/v1/keysCreate an API key.
DELETE/api/v1/keys/{keyId}Revoke an API key. Anything using it stops working immediately.
GET/api/v1/meThe account a credential belongs to.
GET/api/v1/sitesList the account's sites, newest first.
POST/api/v1/sitesCreate a site from a folder of files.
DELETE/api/v1/sites/{id}Delete a site, its files and its form submissions.
GET/api/v1/sites/{id}One site.
PATCH/api/v1/sites/{id}Rename a site, change its web address, or both.
POST/api/v1/sites/{id}/deployReplace every file of a site with the uploaded set.
POST/api/v1/sites/{id}/deploy-tokenIssue a new deploy token for a site. The old one stops working immediately.
POST/api/v1/sites/{id}/deploy/zipReplace every file of a site from a zip archive sent as the raw request body.
GET/api/v1/sites/{id}/filesEvery file a site is serving.
POST/api/v1/sites/{id}/filesAdd or overwrite individual files, leaving the rest of the site alone.
DELETE/api/v1/sites/{id}/submissionsDelete every submission for a site, or every one of a single form.
GET/api/v1/sites/{id}/submissionsOne page of a site's form submissions, newest first.
DELETE/api/v1/sites/{id}/submissions/{submissionId}Delete one submission.
GET/api/v1/sites/{id}/submissions/{submissionId}One submission.
GET/api/v1/sites/{id}/submissions/csvExport a site's form submissions as CSV.
POST/api/v1/sites/{id}/submissions/readMark every unread submission as read.
GET/api/v1/sites/{id}/submissions/summaryHow many submissions a site holds, how many are unread, and which forms exist.
POST/api/v1/sites/importCreate a site by downloading a single page from a known artifact URL.
erreurs

Chaque échec a la même forme

Branche sur le code, jamais sur le message. Les codes sont stables ; la prose est pour celui qui lit le log.

{
  "error": {
    "code": "subdomainTaken",
    "message": "That address is already taken. Try another."
  }
}