Workspace
Create workspaces and their API keys, read members, and set the billing profile that done-for-you orders use.
Get the workspace billing profile
Returns the registrant and postal contact details held for the workspace. These are the details filed with the registrar when the Done For You flow buys a domain, and the address a CAN-SPAM footer must carry. Returns 404 until a profile has been set.
Responses
- 200 The workspace billing profile · BillingProfileResult
- 401 Unauthorized - invalid or missing API key · ErrorUnauthorized
- 404 No billing profile set for this workspace · ErrorBillingProfileNotFound
- 500 Failed to retrieve the billing profile · ErrorResponse
Fields in the 200 response
- billingProfile BillingProfile
13 fields inside billingProfile
- addressLineOne stringExample:
1 Example Street - addressLineTwo stringExample:
Suite 200 - city stringExample:
New York - company stringExample:
Acme Ltd - country string
Country is an ISO 3166-1 alpha-2 code, uppercase.
Example:US - firstName stringExample:
Jane - lastName stringExample:
Doe - phone stringExample:
2125550142 - phoneCc string
PhoneCc is the telephone country calling code without the plus.
Example:1 - postalAddress string
PostalAddress is the address rendered on one line, ready to paste into a compliance footer. Read-only; it is derived from the fields above.
Example:Acme Ltd, 1 Example Street, Suite 200, New York, NY 10001, US - postalCode stringExample:
10001 - state stringExample:
NY - updatedAt string
UpdatedAt is when the profile was last written (RFC3339).
Example:2026-08-03T10:30:00Z
Request
curl -X GET "https://api.emailchaser.com/r/space/billing-profile" \
-H "Authorization: Bearer $EMAILCHASER_API_KEY"Response
{
"billingProfile": {
"addressLineOne": "1 Example Street",
"addressLineTwo": "Suite 200",
"city": "New York",
"company": "Acme Ltd",
"country": "US",
"firstName": "Jane",
"lastName": "Doe",
"phone": "2125550142",
"phoneCc": "1",
"postalAddress": "Acme Ltd, 1 Example Street, Suite 200, New York, NY 10001, US",
"postalCode": "10001",
"state": "NY",
"updatedAt": "2026-08-03T10:30:00Z"
}
}Set the workspace billing profile
Creates or replaces the workspace's registrant and postal contact details. Idempotent: sending the same body twice leaves the same state. Every field except addressLineTwo is required, because incomplete registrant details are filed with the registrar just as readily as complete ones. Set this before ordering domains through /dfy/orders.
Request bodyJSON · UpdateBillingProfileRequest
- addressLineOne string requiredExample:
1 Example Street - addressLineTwo stringExample:
Suite 200 - city string requiredExample:
New York - company string requiredExample:
Acme Ltd - country string required
Country is an ISO 3166-1 alpha-2 code, e.g. US. Case-insensitive on input.
Example:US - firstName string requiredExample:
Jane - lastName string requiredExample:
Doe - phone string requiredExample:
2125550142 - phoneCc string required
PhoneCc is the telephone country calling code without the plus, e.g. 1.
Example:1 - postalCode string requiredExample:
10001 - state string requiredExample:
NY
Responses
- 200 The stored billing profile · BillingProfileResult
- 400 Invalid billing profile · ErrorResponse
- 401 Unauthorized - invalid or missing API key · ErrorUnauthorized
- 500 Failed to save the billing profile · ErrorResponse
Fields in the 200 response
- billingProfile BillingProfile
13 fields inside billingProfile
- addressLineOne stringExample:
1 Example Street - addressLineTwo stringExample:
Suite 200 - city stringExample:
New York - company stringExample:
Acme Ltd - country string
Country is an ISO 3166-1 alpha-2 code, uppercase.
Example:US - firstName stringExample:
Jane - lastName stringExample:
Doe - phone stringExample:
2125550142 - phoneCc string
PhoneCc is the telephone country calling code without the plus.
Example:1 - postalAddress string
PostalAddress is the address rendered on one line, ready to paste into a compliance footer. Read-only; it is derived from the fields above.
Example:Acme Ltd, 1 Example Street, Suite 200, New York, NY 10001, US - postalCode stringExample:
10001 - state stringExample:
NY - updatedAt string
UpdatedAt is when the profile was last written (RFC3339).
Example:2026-08-03T10:30:00Z
Request
curl -X PUT "https://api.emailchaser.com/r/space/billing-profile" \
-H "Authorization: Bearer $EMAILCHASER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"addressLineOne": "1 Example Street",
"addressLineTwo": "Suite 200",
"city": "New York",
"company": "Acme Ltd",
"country": "US",
"firstName": "Jane",
"lastName": "Doe",
"phone": "2125550142",
"phoneCc": "1",
"postalCode": "10001",
"state": "NY"
}'Response
{
"billingProfile": {
"addressLineOne": "1 Example Street",
"addressLineTwo": "Suite 200",
"city": "New York",
"company": "Acme Ltd",
"country": "US",
"firstName": "Jane",
"lastName": "Doe",
"phone": "2125550142",
"phoneCc": "1",
"postalAddress": "Acme Ltd, 1 Example Street, Suite 200, New York, NY 10001, US",
"postalCode": "10001",
"state": "NY",
"updatedAt": "2026-08-03T10:30:00Z"
}
}Get workspace details and members
Returns the workspace behind the API key: campaign counts broken down by status, and the list of members with their roles. Useful for confirming which workspace a key belongs to.
Responses
- 200 Workspace details · SpaceDetails
- 401 Unauthorized - invalid or missing API key · ErrorUnauthorized
- 500 Failed to retrieve workspace details · ErrorResponse
Fields in the 200 response
- completed_campaigns integer
- draft_campaigns integer
- members array of MemberInfo
3 fields inside members
- created_at string
- email_address string
- name string
- not_started_campaigns integer
- paused_campaigns integer
- running_campaigns integer
- space_id integer
- total_campaigns integer
- total_members integer
Request
curl -X GET "https://api.emailchaser.com/r/space/members" \
-H "Authorization: Bearer $EMAILCHASER_API_KEY"Response
{
"completed_campaigns": 123,
"draft_campaigns": 123,
"members": [
{
"created_at": "string",
"email_address": "string",
"name": "Jane Doe"
}
],
"not_started_campaigns": 123,
"paused_campaigns": 123,
"running_campaigns": 123,
"space_id": 123,
"total_campaigns": 123,
"total_members": 123
}List workspaces
Lists the workspaces owned by the API key's workspace owner: the main workspace and its sub-workspaces. isCurrent marks the workspace the calling key is bound to.
Responses
- 200 Workspaces owned by the key's workspace owner · ListWorkspacesResponse
- 401 Unauthorized - invalid or missing API key · ErrorUnauthorized
- 500 Failed to list workspaces · ErrorResponse
Fields in the 200 response
- total integerExample:
3 - workspaces array of WorkspaceItem
5 fields inside workspaces
- createdAt stringExample:
2026-08-19T10:30:00Z - iconUrl string
IconURL is where the workspace's icon image can be loaded from. Empty when the workspace has none. Icons are uploaded in the app.
Example:https://whitelabel-assets.emailchaser.com/workspace-icons/51539607552/1766000000-a1b2c3d4e5f6.png - id integerExample:
51539607552 - isCurrent boolean
IsCurrent is true for the workspace the calling API key is bound to.
Example:false - name stringExample:
Acme Outbound
Request
curl -X GET "https://api.emailchaser.com/r/workspaces" \
-H "Authorization: Bearer $EMAILCHASER_API_KEY"Response
{
"total": 3,
"workspaces": [
{
"createdAt": "2026-08-19T10:30:00Z",
"iconUrl": "https://whitelabel-assets.emailchaser.com/workspace-icons/51539607552/1766000000-a1b2c3d4e5f6.png",
"id": 51539607552,
"isCurrent": false,
"name": "Acme Outbound"
}
]
}Create a workspace
Creates a sub-workspace under the API key's main workspace and, by default, mints a read+write API key bound to the new workspace. The key's fullKey is returned exactly once and cannot be retrieved again, and it never outlives the caller: when the calling key has an expiry, the minted key carries the same expiresAt. Must be called with a main workspace's key: keys bound to sub-workspaces are refused. API keys are included in every plan; workspaces are a Professional-plan feature.
Request bodyJSON · CreateWorkspaceRequest
- generateApiKey boolean
GenerateApiKey mints a read+write API key bound to the new workspace. Defaults to true; pass false to create the workspace only.
Example:true - name string required
Name of the new workspace. Trimmed; 1-60 characters.
Example:Acme Outbound
Responses
- 201 The created workspace and its API key · CreateWorkspaceResponse
- 400 Invalid request body or calling key is not bound to a main workspace · ErrorResponse
- 401 Unauthorized - invalid or missing API key · ErrorUnauthorized
- 403 The workspace's plan does not include workspaces, or the subscription is not active · ErrorResponse
- 500 Failed to create workspace · ErrorResponse
Fields in the 201 response
- apiKey CreatedApiKey
ApiKey is null when generateApiKey was false.
5 fields inside apiKey
- expiresAt string
ExpiresAt is set when the key expires: it inherits the calling key's own expiry, so a temporary key never mints a permanent one. Null for keys minted by a non-expiring key.
Example:2026-09-07T12:00:00Z - fullKey stringExample:
run_abc12345_... - id integerExample:
12 - name stringExample:
Acme Outbound key - scopes array of stringExample:
["read","read_write"]
- note string
Note reminds integrators that fullKey is not retrievable later.
Example:Store apiKey.fullKey now: it cannot be retrieved again. - workspace WorkspaceItem
5 fields inside workspace
- createdAt stringExample:
2026-08-19T10:30:00Z - iconUrl string
IconURL is where the workspace's icon image can be loaded from. Empty when the workspace has none. Icons are uploaded in the app.
Example:https://whitelabel-assets.emailchaser.com/workspace-icons/51539607552/1766000000-a1b2c3d4e5f6.png - id integerExample:
51539607552 - isCurrent boolean
IsCurrent is true for the workspace the calling API key is bound to.
Example:false - name stringExample:
Acme Outbound
Request
curl -X POST "https://api.emailchaser.com/r/workspaces" \
-H "Authorization: Bearer $EMAILCHASER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"generateApiKey": true,
"name": "Acme Outbound"
}'Response
{
"apiKey": {
"expiresAt": "2026-09-07T12:00:00Z",
"fullKey": "run_abc12345_...",
"id": 12,
"name": "Acme Outbound key",
"scopes": [
"read",
"read_write"
]
},
"note": "Store apiKey.fullKey now: it cannot be retrieved again.",
"workspace": {
"createdAt": "2026-08-19T10:30:00Z",
"iconUrl": "https://whitelabel-assets.emailchaser.com/workspace-icons/51539607552/1766000000-a1b2c3d4e5f6.png",
"id": 51539607552,
"isCurrent": false,
"name": "Acme Outbound"
}
}Create an API key for a workspace
Mints an API key bound to a workspace the calling key already owns: its own workspace, or one of its sub-workspaces when called with a main workspace's key. The key returned by POST /r/workspaces is shown once and cannot be retrieved again, so this is how a workspace whose key was lost gets a new one without a UI step. The new key authorizes the named workspace only and never outlives the caller: when the calling key has an expiry, the minted key carries the same expiresAt. fullKey is returned exactly once.
Parameters
- id integer required in path
Workspace ID
Request bodyJSON · CreateWorkspaceApiKeyRequest
- name string
Name shown in the app's API key list. Defaults to "<workspace name> key". Trimmed; up to 60 characters.
Example:VoiceDrop outbound key - readOnly boolean
ReadOnly mints a key that can call GET routes and four POSTs that buy and send nothing (/r/audience/size, /r/setup/ping, /r/dfy/domains/check and /r/lead-finder/searches), and nothing else. Defaults to false, which mints a read+write key.
Example:false
Responses
- 201 The workspace and its new API key · CreateWorkspaceApiKeyResponse
- 400 Invalid workspace ID or request body · ErrorResponse
- 401 Unauthorized - invalid or missing API key · ErrorUnauthorized
- 403 The workspace's plan does not include the API, or the subscription is not active · ErrorResponse
- 404 No such workspace under this account · ErrorResponse
- 500 Failed to create API key · ErrorResponse
Fields in the 201 response
- apiKey CreatedApiKey
5 fields inside apiKey
- expiresAt string
ExpiresAt is set when the key expires: it inherits the calling key's own expiry, so a temporary key never mints a permanent one. Null for keys minted by a non-expiring key.
Example:2026-09-07T12:00:00Z - fullKey stringExample:
run_abc12345_... - id integerExample:
12 - name stringExample:
Acme Outbound key - scopes array of stringExample:
["read","read_write"]
- note string
Note reminds integrators that fullKey is not retrievable later.
Example:Store apiKey.fullKey now: it cannot be retrieved again. - workspace WorkspaceItem
5 fields inside workspace
- createdAt stringExample:
2026-08-19T10:30:00Z - iconUrl string
IconURL is where the workspace's icon image can be loaded from. Empty when the workspace has none. Icons are uploaded in the app.
Example:https://whitelabel-assets.emailchaser.com/workspace-icons/51539607552/1766000000-a1b2c3d4e5f6.png - id integerExample:
51539607552 - isCurrent boolean
IsCurrent is true for the workspace the calling API key is bound to.
Example:false - name stringExample:
Acme Outbound
Request
curl -X POST "https://api.emailchaser.com/r/workspaces/123/api-keys" \
-H "Authorization: Bearer $EMAILCHASER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "VoiceDrop outbound key",
"readOnly": false
}'Response
{
"apiKey": {
"expiresAt": "2026-09-07T12:00:00Z",
"fullKey": "run_abc12345_...",
"id": 12,
"name": "Acme Outbound key",
"scopes": [
"read",
"read_write"
]
},
"note": "Store apiKey.fullKey now: it cannot be retrieved again.",
"workspace": {
"createdAt": "2026-08-19T10:30:00Z",
"iconUrl": "https://whitelabel-assets.emailchaser.com/workspace-icons/51539607552/1766000000-a1b2c3d4e5f6.png",
"id": 51539607552,
"isCurrent": false,
"name": "Acme Outbound"
}
}Generated from the Emailchaser API's own OpenAPI definition, so it always matches the running API.