curl --request POST \
--url https://app.ohmyho.st/v1/projects \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"organization_id": "<string>",
"name": "<string>",
"data_mode": "shared",
"dev_access_mode": "protected",
"region": "us"
}
'import requests
url = "https://app.ohmyho.st/v1/projects"
payload = {
"organization_id": "<string>",
"name": "<string>",
"data_mode": "shared",
"dev_access_mode": "protected",
"region": "us"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
organization_id: '<string>',
name: '<string>',
data_mode: 'shared',
dev_access_mode: 'protected',
region: 'us'
})
};
fetch('https://app.ohmyho.st/v1/projects', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.ohmyho.st/v1/projects",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'organization_id' => '<string>',
'name' => '<string>',
'data_mode' => 'shared',
'dev_access_mode' => 'protected',
'region' => 'us'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.ohmyho.st/v1/projects"
payload := strings.NewReader("{\n \"organization_id\": \"<string>\",\n \"name\": \"<string>\",\n \"data_mode\": \"shared\",\n \"dev_access_mode\": \"protected\",\n \"region\": \"us\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.ohmyho.st/v1/projects")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"organization_id\": \"<string>\",\n \"name\": \"<string>\",\n \"data_mode\": \"shared\",\n \"dev_access_mode\": \"protected\",\n \"region\": \"us\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.ohmyho.st/v1/projects")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"organization_id\": \"<string>\",\n \"name\": \"<string>\",\n \"data_mode\": \"shared\",\n \"dev_access_mode\": \"protected\",\n \"region\": \"us\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"state": "queued",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"blocking_operation_id": "<string>",
"deployment_id": "<string>",
"result": {},
"error": {
"code": "operation_failed",
"message": "<string>",
"retryable": false,
"suggested_action": "<string>"
},
"progress": {
"phase": "queued",
"project_id": "<string>",
"deployment_id": "<string>",
"observed_at": "2023-11-07T05:31:56Z",
"next_poll_after_seconds": 60,
"suggested_action": "<string>",
"build_completed_at": "2023-11-07T05:31:56Z"
},
"reconciliation": {
"state": "required",
"attempt_id": "<string>",
"observed_at": "2023-11-07T05:31:56Z",
"suggested_action": "<string>"
}
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "https://docs.ohmyho.st/errors/idempotency-key-reused",
"title": "Idempotency key reused",
"status": 409,
"code": "idempotency_key_reused",
"request_id": "req_01J00000000000000000000000",
"retryable": false,
"suggested_action": "Retry with a new idempotency key."
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}Create a project
Atomically records the project and a durable operation for asynchronous processing.
curl --request POST \
--url https://app.ohmyho.st/v1/projects \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"organization_id": "<string>",
"name": "<string>",
"data_mode": "shared",
"dev_access_mode": "protected",
"region": "us"
}
'import requests
url = "https://app.ohmyho.st/v1/projects"
payload = {
"organization_id": "<string>",
"name": "<string>",
"data_mode": "shared",
"dev_access_mode": "protected",
"region": "us"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
organization_id: '<string>',
name: '<string>',
data_mode: 'shared',
dev_access_mode: 'protected',
region: 'us'
})
};
fetch('https://app.ohmyho.st/v1/projects', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.ohmyho.st/v1/projects",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'organization_id' => '<string>',
'name' => '<string>',
'data_mode' => 'shared',
'dev_access_mode' => 'protected',
'region' => 'us'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.ohmyho.st/v1/projects"
payload := strings.NewReader("{\n \"organization_id\": \"<string>\",\n \"name\": \"<string>\",\n \"data_mode\": \"shared\",\n \"dev_access_mode\": \"protected\",\n \"region\": \"us\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.ohmyho.st/v1/projects")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"organization_id\": \"<string>\",\n \"name\": \"<string>\",\n \"data_mode\": \"shared\",\n \"dev_access_mode\": \"protected\",\n \"region\": \"us\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.ohmyho.st/v1/projects")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"organization_id\": \"<string>\",\n \"name\": \"<string>\",\n \"data_mode\": \"shared\",\n \"dev_access_mode\": \"protected\",\n \"region\": \"us\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"state": "queued",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"blocking_operation_id": "<string>",
"deployment_id": "<string>",
"result": {},
"error": {
"code": "operation_failed",
"message": "<string>",
"retryable": false,
"suggested_action": "<string>"
},
"progress": {
"phase": "queued",
"project_id": "<string>",
"deployment_id": "<string>",
"observed_at": "2023-11-07T05:31:56Z",
"next_poll_after_seconds": 60,
"suggested_action": "<string>",
"build_completed_at": "2023-11-07T05:31:56Z"
},
"reconciliation": {
"state": "required",
"attempt_id": "<string>",
"observed_at": "2023-11-07T05:31:56Z",
"suggested_action": "<string>"
}
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "https://docs.ohmyho.st/errors/idempotency-key-reused",
"title": "Idempotency key reused",
"status": 409,
"code": "idempotency_key_reused",
"request_id": "req_01J00000000000000000000000",
"retryable": false,
"suggested_action": "Retry with a new idempotency key."
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "invalid_request",
"request_id": "<string>",
"retryable": true,
"suggested_action": "<string>",
"detail": "<string>",
"instance": "<string>",
"retry_after_seconds": 43200
}Authorizations
WorkOS access JWT or a user-owned WorkOS API key. User keys are bound to one organization and restricted to their enabled product permissions. Session-only onboarding and session revocation require an interactive access JWT. No cookie session is assumed.
Headers
Optional caller-provided correlation identifier.
1 - 128Identifies one mutation and its canonical request payload.
1 - 128Body
Phase 1 project creation request. The server assigns resource identifiers.
^[0-9A-HJKMNP-TV-Z]{26}$1 - 128^\S(?:.*\S)?$Optional at creation, default shared. shared uses one data area across Dev/Prod; isolated gives each environment its own database/Auth records and file namespace. The four Owner-confirmed data-change actions reassign or reset areas without copying data or files and without a special change fee; ordinary measured resource consumption still applies. A reset or merge removes the named Dev resources. Promotion applies pending schema migrations to isolated Prod without copying Dev data.
shared, isolated protected, public Chosen when the project is created and immutable afterwards. us (default) places the project's database, files, build sandbox and build objects in the US; eu places them in the EU. Prices are identical. ohmyhost.yaml storage.jurisdiction must equal this value.
us, eu Response
The mutation was accepted for asynchronous processing.
Durable record returned for an accepted asynchronous mutation. Optional reconciliation is a current observation for queued/running work, separate from immutable terminal state. A completed reconciliation attempt alone does not mean the operation succeeded.
^[0-9A-HJKMNP-TV-Z]{26}$queued, running, succeeded, failed, cancelled The active operation holding this queued operation's project mutation claim.
^[0-9A-HJKMNP-TV-Z]{26}$The deployment this operation created (deploy, promotion or rollback), in every state. After a failure, read its diagnostics with deployment logs.
^[0-9A-HJKMNP-TV-Z]{26}$Show child attributes
Show child attributes
Current deployment dependency observation, separate from immutable operation history. Poll the same operation; mail readiness does not mean application activation.
Show child attributes
Show child attributes
Show child attributes
Show child attributes