Lahat ng kayang gawin ng dashboard, mula sa terminal mo
Isang account key. Ilista ang mga site mo, mag-deploy sa kanila, palitan ang pangalan, basahin ang nakolekta ng mga form mo, burahin sila — sa payak na HTTP, mula sa script, sa CI job, o sa isang agent.
Tatlong command
Gumawa ng key sa dashboard mo, tiyaking gumagana, at ilagay online ang isang folder. Napupunta ang key sa Authorization header sa bawat tawag.
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"
Hindi maaaring maghiwalay ang web app at ang API
Isang beses lang idineklara ang bawat kakayahan, sa iisang file, at doon galing ang dashboard at ang API na ito. Ginagawa ang openapi.json mula sa deklarasyong iyon, at nabibigo ang build kapag hindi sila tugma. Kaya hindi ito dokumentasyong naglalarawan ng produkto — ito mismo ang pinaggagawan ng produkto.
- Isang implementasyon bawat kakayahan, tinatawag ng web app at ng script mo nang pareho.
- Ginagawa ang openapi.json, hindi kailanman sinusulat sa kamay, at inihahain sa /openapi.json.
- Nabibigo ang build sa sandaling hindi na magkasundo ang route, ang kontrata at ang dokumento.
Sa isang key, sa iyo agad ang site
Gumagana pa rin ang pag-deploy nang walang account at gayon pa rin sa hinaharap — makakakuha ka ng pribadong claim link na bubuksan mo mamaya. Magpadala ng key sa parehong tawag at wala nang dapat i-claim: nasa account mo na ang site mula sa unang byte, at hindi ito nag-e-expire.
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
Ang buong ibabaw
Nasa OpenAPI document ang buong hugis ng request at response.
| method | path | ano ang ginagawa |
|---|---|---|
| GET | /api/v1 | Check that a credential works. |
| GET | /api/v1/keys | The account's API keys. Revoked keys are not listed. |
| POST | /api/v1/keys | Create an API key. |
| DELETE | /api/v1/keys/{keyId} | Revoke an API key. Anything using it stops working immediately. |
| GET | /api/v1/me | The account a credential belongs to. |
| GET | /api/v1/sites | List the account's sites, newest first. |
| POST | /api/v1/sites | Create 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}/deploy | Replace every file of a site with the uploaded set. |
| POST | /api/v1/sites/{id}/deploy-token | Issue a new deploy token for a site. The old one stops working immediately. |
| POST | /api/v1/sites/{id}/deploy/zip | Replace every file of a site from a zip archive sent as the raw request body. |
| GET | /api/v1/sites/{id}/files | Every file a site is serving. |
| POST | /api/v1/sites/{id}/files | Add or overwrite individual files, leaving the rest of the site alone. |
| DELETE | /api/v1/sites/{id}/submissions | Delete every submission for a site, or every one of a single form. |
| GET | /api/v1/sites/{id}/submissions | One 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/csv | Export a site's form submissions as CSV. |
| POST | /api/v1/sites/{id}/submissions/read | Mark every unread submission as read. |
| GET | /api/v1/sites/{id}/submissions/summary | How many submissions a site holds, how many are unread, and which forms exist. |
| POST | /api/v1/sites/import | Create a site by downloading a single page from a known artifact URL. |
Iisa ang hugis ng bawat pagkabigo
Sa code ka magsanga, huwag kailanman sa mensahe. Matatag ang mga code; ang teksto ay para sa kung sinuman ang magbabasa ng log.
{
"error": {
"code": "subdomainTaken",
"message": "That address is already taken. Try another."
}
}