http api

대시보드가 하는 모든 일을, 터미널에서

계정 키 하나면 됩니다. 사이트 목록 보기, 배포하기, 이름 바꾸기, 폼이 모은 내용 읽기, 삭제하기 — 평범한 HTTP로, 스크립트에서든 CI 작업에서든 에이전트에서든.

빠른 시작

명령 세 개

대시보드에서 키를 만들고, 잘 되는지 확인한 뒤, 폴더를 올리세요. 키는 매 호출마다 Authorization 헤더에 넣습니다.

키가 되는지 확인
curl -H "Authorization: Bearer hvs_…" https://harvis.dev/api/v1
계정에 뭐가 있는지 보기
curl -H "Authorization: Bearer hvs_…" https://harvis.dev/api/v1/sites
폴더 게시하기
curl -X POST https://harvis.dev/api/v1/sites \
  -H "Authorization: Bearer hvs_…" \
  -F "files=@index.html" -F "paths=index.html"
하나의 계약

웹 앱과 API는 어긋날 수 없습니다

모든 기능은 한 파일에서 한 번만 선언되고, 대시보드도 이 API도 거기서 만들어집니다. openapi.json은 그 선언에서 생성되며, 둘이 어긋나면 빌드가 실패합니다. 그러니 이건 제품을 설명하는 문서가 아니라 — 제품을 이루고 있는 것 자체입니다.

  • 기능마다 구현은 하나. 웹 앱도 당신의 스크립트도 같은 것을 호출합니다.
  • openapi.json은 생성되는 파일이고 손으로 쓰지 않으며 /openapi.json에서 제공됩니다.
  • 라우트와 계약과 문서가 어긋나는 순간 빌드가 실패합니다.
배포

키가 있으면 사이트는 곧바로 내 것

계정 없이 배포하는 방식도 계속 됩니다 — 나중에 열 수 있는 비공개 소유권 링크를 받습니다. 같은 호출에 키를 함께 보내면 소유할 것이 남지 않습니다. 첫 바이트부터 사이트는 계정 안에 있고, 만료되지 않습니다.

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
엔드포인트

전체 표면

요청과 응답의 전체 형태는 OpenAPI 문서에 있습니다.

메서드경로하는 일
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.
오류

모든 실패는 같은 모양입니다

메시지가 아니라 코드로 분기하세요. 코드는 안정적이고, 문장은 로그를 읽는 사람을 위한 것입니다.

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