API reference / Admin
/v2/projectsCreate a tenant
- Operation
createProject- Authentication
- API key
Internal. Requires `projects:write`. Returns the tenant’s first key, once.
Request
Body
idstringrequirednamestringrequiredplanstringone of: developerstartergrowthenterprise
data_residencystringnullSet when a tenant’s data may not leave a jurisdiction. Ethiopia requires local storage of locally-collected personal data (Proclamation 1321/2024, Art. 22(1)). Null means no requirement is recorded. **Recorded only** — nothing enforces it yet.
Responses
keystringrequiredThe full key. Returned exactly once — we store only a SHA-256 digest, so it cannot be recovered or re-displayed, including by us.
prefixstringrequiredenvironmentstringone of: livetest
kindstringrequiredWhich kind of key this is, and the field to branch on. `publishable` keys are capped to a scope ceiling and rejected outside their origin allowlist; `secret` keys are not.
one of: secretpublishable
scopesstring[]dropped_scopesstring[]Requested and not granted. Present only when something was dropped, and named rather than silently omitted so nobody builds against a capability they were refused.
dropped_reasonstringWhy anything in `dropped_scopes` was dropped. Present only alongside it.
warningstringrequirederrorobjectrequirederrorobjectrequirederrorobjectrequirederrorobjectrequirederrorobjectrequiredExample
curl -X POST https://api.haavisa.com/v2/projects \
-H "Authorization: Bearer $HAAVISA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "<id>",
"name": "<name>"
}'More in Admin
GET/v1/admin/activityGET/v1/admin/applicant-usersPOST/v1/admin/applicantsGET/v1/admin/applicationsGET/v1/admin/applications/{id}POST/v1/admin/applications/{id}/decision-documentPOST/v1/admin/applications/{id}/documents-requestPOST/v1/admin/applications/{id}/documents-request/{requestId}/reviewGET/v1/admin/applications/{id}/documents/{documentId}POST/v1/admin/applications/{id}/emailGET/v1/admin/applications/{id}/evidence/{filename}POST/v1/admin/applications/{id}/government-paymentPOST/v1/admin/applications/{id}/government-payment/recordPOST/v1/admin/applications/{id}/requirements/reviewPOST/v1/admin/applications/{id}/status-checkPOST/v1/admin/applications/{id}/submissionPOST/v1/admin/applications/{id}/submission/enqueueGET/v1/admin/applications/{id}/timelineGET/v1/admin/automationGET/v1/admin/customersGET/v1/admin/customers/{id}POST/v1/admin/customers/{id}/verification-emailGET/v1/admin/documentsGET/v1/admin/government-paymentsGET/v1/admin/mailboxGET/v1/admin/mailbox/{source}/{messageId}GET/v1/admin/notificationsPOST/v1/admin/notifications/{id}/requeueGET/v1/admin/operatorsPOST/v1/admin/operatorsPATCH/v1/admin/operators/{email}POST/v1/admin/operators/{email}/invitationGET/v1/admin/operators/authorization/{email}GET/v1/admin/payment-recoveryPOST/v1/admin/payment-recovery/{id}/remindGET/v1/admin/paymentsPATCH/v1/admin/products/{code}/availabilityPATCH/v1/admin/products/{code}/pricingPATCH/v1/admin/service-tiers/{id}/pricingGET/v1/admin/statsPOST/v1/admin/stripe/catalog/syncGET/v1/admin/system/submission-workerPATCH/v1/admin/system/submission-workerGET/v1/admin/visa-dataPATCH/v1/admin/visa-data/{destination}/availabilityPOST/v1/admin/visa-data/{destination}/requirementsPOST/v1/admin/visa-data/{destination}/sourcesDELETE/v1/admin/visa-data/sources/{id}PATCH/v1/admin/visa-data/sources/{id}GET/v1/checkout-returnGET/v1/rules/freshnessGET/v2/projectsGET/v2/projects/{id}PUT/v2/projects/{id}DELETE/v2/projects/{id}/keys/{prefix}GET/v2/projects/{id}/usersPOST/v2/projects/{id}/users
Something unclear? The eligibility guide explains the model behind the answers; the errors guide covers the envelope.