curl --request PUT \
--url https://api.gigstack.io/v2/teams/{id}/email-domain \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"operation_id": "<string>",
"domain": "<string>",
"subdomain": "<string>"
}
'const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({operation_id: '<string>', domain: '<string>', subdomain: '<string>'})
};
fetch('https://api.gigstack.io/v2/teams/{id}/email-domain', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.gigstack.io/v2/teams/{id}/email-domain"
payload = {
"operation_id": "<string>",
"domain": "<string>",
"subdomain": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text){
"success": true,
"data": {
"id": "<string>",
"action": "set",
"status": "pending",
"created_at": 123,
"started_at": 123,
"completed_at": 123,
"recovery_available_at": 123,
"result": {
"domain": {
"domain": "<string>",
"subdomain": "<string>",
"full_domain": "<string>",
"valid": true,
"dns_setup": {},
"configured": true
},
"previous_provider_domain_retained": true
},
"error_code": "<string>",
"resolution": {
"action": "released_for_new_operation",
"resolved_at": 123
}
},
"timestamp": 123
}Set custom email domain
Verified personal Firebase/MCP credential required. Team API/OAuth creator identity is not accepted. Scope is shared across live/test; staging may use the same configured SendGrid account. Test mode does not isolate provider effects. Current administrator required. Caller saves UUIDv4 operation_id before submitting. Domain/subdomain normalized lowercase/IDNA with strict DNS labels. Replacing local configuration retains the previous provider domain and reports that fact. Completed setup can still require customer DNS changes. Set, validate, remove and reconciliation reject unverified legacy ownership with 409 domain_migration_required; the server does not migrate ownership from a client-writable provider identifier.
curl --request PUT \
--url https://api.gigstack.io/v2/teams/{id}/email-domain \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"operation_id": "<string>",
"domain": "<string>",
"subdomain": "<string>"
}
'const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({operation_id: '<string>', domain: '<string>', subdomain: '<string>'})
};
fetch('https://api.gigstack.io/v2/teams/{id}/email-domain', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.gigstack.io/v2/teams/{id}/email-domain"
payload = {
"operation_id": "<string>",
"domain": "<string>",
"subdomain": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text){
"success": true,
"data": {
"id": "<string>",
"action": "set",
"status": "pending",
"created_at": 123,
"started_at": 123,
"completed_at": 123,
"recovery_available_at": 123,
"result": {
"domain": {
"domain": "<string>",
"subdomain": "<string>",
"full_domain": "<string>",
"valid": true,
"dns_setup": {},
"configured": true
},
"previous_provider_domain_retained": true
},
"error_code": "<string>",
"resolution": {
"action": "released_for_new_operation",
"resolved_at": 123
}
},
"timestamp": 123
}Authorizations
Authentication Method: HTTP Bearer token.
The runtime requires the literal Bearer prefix — a bare token in the
Authorization header is rejected with 401 unauthorized.
Header Format: Authorization: Bearer YOUR_API_KEY
Your API key is a JWT. Live keys operate on live data (livemode: true);
test keys operate on isolated test data (livemode: false).
Get your key at: app.gigstack.pro/settings?tab=api
Errors: credential failures are answered by the authentication layer with a raw
{ "message": … } body, not the standardized envelope — 401 for a missing, malformed or
expired token, 403 for a revoked key or a plan without API access. See the Unauthorized
and AuthForbidden responses.