Vector Pro
Provision, deploy, and manage serverless WordPress sites on AWS Lambda infrastructure with enterprise-grade CDN, WAF, and DNS services.
https://api.builtfast.com/api/v1/vector
Authentication
All requests require Bearer token authentication via the Authorization header.
Authorization: Bearer {YOUR_API_TOKEN}
Quick Start
POST/sites
ssh.myvectorsite.com
POST/deployments
Response Format
{
"data": {
"id": "01HQ7KXYZ...",
"type": "production",
"status": "active"
},
"message": "Success",
"http_status": 200
}
{
"data": [
{ "id": "01HQ7K..." },
{ "id": "01HQ7L..." }
],
"links": { "next": "..." },
"meta": { "total": 42 }
}
{
"errors": {
"type": ["Required"],
"php_version": ["Invalid"]
},
"message": "Validation failed"
}
Status Codes
200Success201Created202Accepted (async)400Bad request401Unauthorized404Not found422Validation error429Rate limitedRate Limits
120/min60/hour30/hour60/hour10/hour10/hour10/hourX-RateLimit-Remaining
Pagination
pagePage number (default: 1)per_pageItems per page (max: 100)links and meta objects
Async Operations
Site creation, environments, and deployments return 202 and process asynchronously.
SDKs & Tools
composer require built-fast/vector-pro-sdk
npm install @built-fast/vector-pro-sdk
brew install built-fast/devtools/vector-cli
Click the sparkle icon on any endpoint to copy its OpenAPI spec—ready to paste into your favorite LLM.
Account
Manage your Vector Pro account settings including API keys, SSH keys, and global secrets.
Get Account Summary
Retrieves a summary of the authenticated account’s Vector Pro information including owner details, cluster DNS endpoints, verified domains, site/environment counts grouped by status, deployment metrics, backup counts, and recent activity.
Site counts exclude sites in a terminal state (terminated, termination_requested,
canceled). Environment counts exclude environments in a terminal state (terminated,
terminating). Those statuses are therefore omitted from the by_status breakdowns
and are not included in any of the total/convenience counts.
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/account" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->account->getSummary();
const response = await client.account.getSummary();
Response
{
"data": {
"owner": {
"name": "John Doe",
"email": "[email protected]"
},
"account": {
"name": "My Account",
"company": "Acme Corp"
},
"partner": {
"external_customer_url": "https://myapp.com/customers/YOUR_ID"
},
"cluster": {
"alb_dns_name": "alb-abc123.us-west-2.elb.amazonaws.com",
"aurora_cluster_endpoint": "cluster.abc123.us-east-1.rds.amazonaws.com",
"ssh_nlb_dns": "nlb-abc123.us-west-2.elb.amazonaws.com"
},
"domains": [
"example.com",
"example.org"
],
"sites": {
"total": 4,
"by_status": {
"pending": 0,
"activation_requested": 0,
"active": 3,
"suspension_requested": 0,
"suspended": 1,
"unsuspension_requested": 0
}
},
"environments": {
"total": 7,
"by_status": {
"pending": 1,
"provisioning": 0,
"active": 5,
"suspending": 0,
"suspended": 1,
"unsuspending": 0,
"failed": 0
}
},
"total_sites": 4,
"pending_sites": 0,
"total_environments": 7,
"production_environments": 3,
"deployments_30d": 12,
"failed_deployments_30d": 1,
"active_backups": 4,
"recent_activity": [],
"recent_deployments": []
},
"message": "Account summary retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Update Account Settings
Update partner-level configuration on the authenticated account. The most
important setting today is external_customer_url, a URL template containing
the literal token YOUR_ID. When a site’s your_customer_id is rendered in
the Vector Pro control panel, that token is substituted with the value and
the customer ID is shown as a link to the partner’s own system.
On success this endpoint returns the same shape as GET /vector/account so
clients can refresh their cached account state in a single round trip.
Body Parameters
| Name | Type | Description |
|---|---|---|
|
external_customer_url
optional
|
string |
nullable A URL template that must contain the literal token Example:
"https://myapp.com/customers/YOUR_ID" |
Response Codes
Request
curl -X PATCH \
"https://api.builtfast.com/api/v1/vector/account" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"external_customer_url":"https://myapp.com/customers/YOUR_ID"}'
$response = $vectorPro
->account
->patch([
'external_customer_url' => 'https://myapp.com/customers/YOUR_ID',
]);
const response = await vectorPro
.account
.patch({
external_customer_url: 'https://myapp.com/customers/YOUR_ID',
});
Response
{
"data": {
"owner": {
"name": "John Doe",
"email": "[email protected]"
},
"account": {
"name": "My Account",
"company": "Acme Corp"
},
"partner": {
"external_customer_url": "https://myapp.com/customers/YOUR_ID"
},
"cluster": null,
"domains": [],
"sites": {
"total": 0,
"by_status": {}
},
"environments": {
"total": 0,
"by_status": {}
}
},
"message": "Account updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"external_customer_url": [
"The external customer URL must contain the literal token YOUR_ID, which is replaced with each site's your_customer_id when the link is rendered."
]
},
"message": "Validation failed",
"http_status": 422
}
API Keys
Manage API access tokens for authentication. Tokens provide Bearer token authentication for all API requests.
The plain text token is returned only once when created - store it securely as it cannot be retrieved again. Tokens can be revoked at any time.
List API Keys
Retrieves a paginated list of API keys for the authenticated user. Token values are never returned - only metadata like name, creation date, and last used timestamp.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/api-keys?per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$apiKeys = $client->account->apiKeys->list();
const apiKeys = await client.account.apiKeys.list();
Response
{
"data": [
{
"name": "Production API Key",
"abilities": [
"*"
],
"last_used_at": "2025-01-15T12:00:00+00:00",
"expires_at": null,
"created_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "API keys retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
Create API Key
Creates a new API key for the authenticated user.
The API key is returned ONLY in this response. Store it securely—it cannot be retrieved again.
Use this token in the Authorization header for all API requests.
Abilities
Abilities control what operations the token can perform. Available abilities:
*- Full access (default)mcp- Full MCP access (for AI assistants like Claude)account:read- Read account informationsite:read- Read sites, environments, deployments, database operationssite:write- Manage sites, environments, deployments, database import/exportdomain:read- Read domainsdomain:write- Manage domainslog:read- Read site logscdn:read- Read CDN settingscdn:write- Manage CDN settings and cachewebhook:read- Read webhookswebhook:write- Manage webhookssecret:read- Read API keys and global secretssecret:write- Manage API keys and global secretssshkey:read- Read SSH keyssshkey:write- Manage SSH keysevents:read- Read event logs
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
required
|
string |
A descriptive name for this API key. Example:
"Production API Key" |
|
abilities
optional
|
string[] |
Optional array of abilities. Defaults to [“*”] for full access. Example:
["site:read","site:write"] |
|
expires_at
optional
|
datetime |
Optional expiration date for the token. Must be in the future. Example:
"2025-12-31T23:59:59+00:00" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/api-keys" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"Production API Key","abilities":["site:read","site:write"],"expires_at":"2025-12-31T23:59:59+00:00"}'
$apiKey = $client->account->apiKeys->create([
'name' => 'Production API Key',
'abilities' => ['site:read', 'site:write'],
'expires_at' => '2025-12-31T23:59:59+00:00',
]);
const apiKey = await client.account.apiKeys.create({
name: 'Production API Key',
abilities: ['site:read', 'site:write'],
expires_at: '2025-12-31T23:59:59+00:00',
});
Response
{
"data": {
"name": "Production API Key",
"token": "1|a1b2c3d4e5f6789012345678901234567890123456789012345678901234abcd",
"abilities": [
"*"
],
"expires_at": null,
"created_at": "2025-01-15T12:00:00+00:00"
},
"message": "API key created successfully. Store this token securely - it will not be shown again.",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"errors": {
"name": [
"The name field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete API Key
Deletes an API key. You cannot delete the token currently being used for authentication. This operation is irreversible.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
token
required
|
integer |
The API key ID. Example:
1 |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/api-keys/1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->account->apiKeys->delete('1');
const response = await client.account.apiKeys.delete('1');
Response
{
"data": {
"name": "Production API Key",
"abilities": [
"*"
],
"last_used_at": "2025-01-15T12:00:00+00:00",
"expires_at": null,
"created_at": "2025-01-15T12:00:00+00:00"
},
"message": "API key deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Cannot delete the token currently in use",
"http_status": 403
}
{
"data": {},
"message": "API key not found",
"http_status": 404
}
Secrets
Manage account-level secrets and environment variables that are available to all sites within your account. These are injected during site deployment.
Global secrets apply to all environments across all sites in your account. For environment-specific secrets, use the Environment Secrets API instead.
Items with is_secret=true (the default) are stored in AWS Secrets Manager and their values
are never returned in API responses. Items with is_secret=false are stored as Lambda
environment variables and their values ARE returned in API responses.
Certain keys are reserved for system use and cannot be used.
List Secrets
Retrieves a paginated list of all global secrets and environment variables for your account.
Values are only included for environment variables (is_secret=false).
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
10 |
|
page
optional
|
integer |
Page number for pagination. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/global-secrets?per_page=10&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$secrets = $client->account->secrets->list();
const secrets = await client.account.secrets.list();
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
{
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"key": "APP_ENV",
"is_secret": false,
"value": "production",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Global secrets retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Get Secret
Retrieves details of a specific global secret or environment variable.
The value is only included for environment variables (is_secret=false).
URL Parameters
| Name | Type | Description |
|---|---|---|
|
secret
required
|
string |
The secret ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/global-secrets/01jfgxk4nqrst5vwx9yz0abcde" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$secret = $client->account->secrets->get('01jfgxk4nqrst5vwx9yz0abcde');
const secret = await client.account.secrets.get('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Global secret retrieved successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"key": "APP_ENV",
"is_secret": false,
"value": "production",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Global secret retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Global secret not found",
"http_status": 404
}
Create Secret
Creates a new global secret or environment variable for your account. It will be available to all sites within your account during deployment.
Set is_secret to false to create a plain environment variable instead of a secret.
Environment variables are stored as Lambda env vars (cheaper) and their values are
returned in API responses. Secrets are stored in AWS Secrets Manager and their values
are never returned.
The following keys are reserved and cannot be used: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT, AUTOMATIC_UPDATER_DISABLED, DISABLE_WP_CRON, DISALLOW_FILE_EDIT, DISALLOW_FILE_MODS, DOMAIN_CURRENT_SITE, WP_HOME, WP_SITEURL, YMIR_ASSETS_PATH, YMIR_ASSETS_URL, YMIR_CACHE_PREFIX, YMIR_CACHE_TABLE, YMIR_CDN_IMAGE_PROCESSING_ENABLED, YMIR_DISTRIBUTION_ID, YMIR_DOMAIN_NAMES, YMIR_ENVIRONMENT, YMIR_MAX_EXECUTION_TIME, YMIR_PRIMARY_DOMAIN_NAME, YMIR_PROJECT_TYPE, YMIR_PUBLIC_STORE, YMIR_REDIS_ENDPOINT, YMIR_SECRETS_PATH, YMIR_UPLOAD_URL, _HANDLER, AWS_ACCESS_KEY_ID, AWS_EXECUTION_ENV, AWS_LAMBDA_FUNCTION_MEMORY_SIZE, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_VERSION, AWS_LAMBDA_LOG_GROUP_NAME, AWS_LAMBDA_LOG_STREAM_NAME, AWS_LAMBDA_RUNTIME_API, AWS_REGION, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, LAMBDA_RUNTIME_DIR, LAMBDA_TASK_ROOT, TZ
Body Parameters
| Name | Type | Description |
|---|---|---|
|
key
required
|
string |
The secret key name. Must start with a letter and contain only uppercase letters, numbers, and underscores. Example:
"STRIPE_SECRET_KEY" |
|
value
required
|
string |
The secret value. Example:
"sk_live_xxxx" |
|
is_secret
optional
|
boolean |
Whether this is a secret (stored in AWS Secrets Manager) or a plain environment variable. Default: true. Example:
true |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/global-secrets" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"key":"STRIPE_SECRET_KEY","value":"sk_live_xxxx","is_secret":true}'
$secret = $client->account->secrets->create([
'key' => 'STRIPE_SECRET_KEY',
'value' => 'sk_live_xxxx',
'is_secret' => true,
]);
const secret = await client.account.secrets.create({
key: 'STRIPE_SECRET_KEY',
value: 'sk_live_xxxx',
is_secret: true,
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Global secret created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"key": [
"The secret key is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Update Secret
Updates an existing global secret or environment variable. You can update the key, value, is_secret flag, or any combination.
The following keys are reserved and cannot be used: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT, AUTOMATIC_UPDATER_DISABLED, DISABLE_WP_CRON, DISALLOW_FILE_EDIT, DISALLOW_FILE_MODS, DOMAIN_CURRENT_SITE, WP_HOME, WP_SITEURL, YMIR_ASSETS_PATH, YMIR_ASSETS_URL, YMIR_CACHE_PREFIX, YMIR_CACHE_TABLE, YMIR_CDN_IMAGE_PROCESSING_ENABLED, YMIR_DISTRIBUTION_ID, YMIR_DOMAIN_NAMES, YMIR_ENVIRONMENT, YMIR_MAX_EXECUTION_TIME, YMIR_PRIMARY_DOMAIN_NAME, YMIR_PROJECT_TYPE, YMIR_PUBLIC_STORE, YMIR_REDIS_ENDPOINT, YMIR_SECRETS_PATH, YMIR_UPLOAD_URL, _HANDLER, AWS_ACCESS_KEY_ID, AWS_EXECUTION_ENV, AWS_LAMBDA_FUNCTION_MEMORY_SIZE, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_VERSION, AWS_LAMBDA_LOG_GROUP_NAME, AWS_LAMBDA_LOG_STREAM_NAME, AWS_LAMBDA_RUNTIME_API, AWS_REGION, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, LAMBDA_RUNTIME_DIR, LAMBDA_TASK_ROOT, TZ
URL Parameters
| Name | Type | Description |
|---|---|---|
|
secret
required
|
string |
The secret ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
key
optional
|
string |
The new secret key name. Must start with a letter and contain only uppercase letters, numbers, and underscores. Example:
"STRIPE_API_KEY" |
|
value
optional
|
string |
The new secret value. Example:
"sk_live_yyyy" |
|
is_secret
optional
|
boolean |
Whether this is a secret or a plain environment variable. Example:
true |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/global-secrets/01jfgxk4nqrst5vwx9yz0abcde" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"key":"STRIPE_API_KEY","value":"sk_live_yyyy","is_secret":true}'
$secret = $client->account->secrets->update(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'key' => 'STRIPE_API_KEY',
'value' => 'sk_live_yyyy',
'is_secret' => true,
]
);
const secret = await client.account.secrets.update(
'01jfgxk4nqrst5vwx9yz0abcde',
{
key: 'STRIPE_API_KEY',
value: 'sk_live_yyyy',
is_secret: true,
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_API_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Global secret updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Global secret not found",
"http_status": 404
}
{
"data": {},
"errors": {
"key": [
"The secret key must start with a letter and contain only uppercase letters, numbers, and underscores."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Secret
Deletes a global secret from your account.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
secret
required
|
string |
The secret ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/global-secrets/01jfgxk4nqrst5vwx9yz0abcde" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->account->secrets->delete('01jfgxk4nqrst5vwx9yz0abcde');
const response = await client.account.secrets.delete('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Global secret deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Global secret not found",
"http_status": 404
}
SSH Keys
Manage account-level default SSH keys. These keys serve as templates that are automatically installed on new dev sites when they are created.
Important: Changes to account-level keys do not affect existing sites. To add or remove keys from an existing site, use the site-specific SSH key endpoints instead.
List SSH Keys
Retrieves a paginated list of account-level default SSH keys. These are template keys that will be installed on new dev sites.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/ssh-keys?per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$sshKeys = $client->account->sshKeys->list();
const sshKeys = await client.account.sshKeys.list();
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"account_id": 1,
"vector_site_id": null,
"name": "deploy key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "SSH keys retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Get SSH Key
Retrieves details of a specific account-level SSH key.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
key
required
|
string |
The SSH key ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/ssh-keys/01jfgxk4nqrst5vwx9yz0abcdi" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$sshKey = $client->account->sshKeys->get('01jfgxk4nqrst5vwx9yz0abcdi');
const sshKey = await client.account.sshKeys.get('01jfgxk4nqrst5vwx9yz0abcdi');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"account_id": 1,
"vector_site_id": null,
"name": "deploy key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSH key retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "SSH key not found",
"http_status": 404
}
Create SSH Key
Creates a new account-level default SSH key. This key will be automatically installed on any new dev sites created after this point.
Note: This does not affect existing sites. To add a key to an existing site, use the site-specific SSH key endpoint.
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
required
|
string |
A friendly name for the SSH key. Example:
"deploy key" |
|
public_key
required
|
string |
The SSH public key in OpenSSH format. Example:
"ssh-rsa AAAAB3NzaC1yc2EA... user@host" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/ssh-keys" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"deploy key","public_key":"ssh-rsa AAAAB3NzaC1yc2EA... user@host"}'
$sshKey = $client->account->sshKeys->create([
'name' => 'deploy key',
'public_key' => 'ssh-rsa AAAAB3NzaC1yc2EA... user@host',
]);
const sshKey = await client.account.sshKeys.create({
name: 'deploy key',
public_key: 'ssh-rsa AAAAB3NzaC1yc2EA... user@host',
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"account_id": 1,
"vector_site_id": null,
"name": "deploy key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSH key created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"public_key": [
"Unable to parse SSH public key. Ensure it is in valid OpenSSH format."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"errors": {
"public_key": [
"An SSH key with this fingerprint already exists for this account."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete SSH Key
Deletes an account-level default SSH key. This does not remove the key from any existing sites where it has already been installed.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
key
required
|
string |
The SSH key ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/ssh-keys/01jfgxk4nqrst5vwx9yz0abcdi" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->account->sshKeys->delete('01jfgxk4nqrst5vwx9yz0abcdi');
const response = await client.account.sshKeys.delete('01jfgxk4nqrst5vwx9yz0abcdi');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"account_id": 1,
"vector_site_id": null,
"name": "deploy key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSH key deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "SSH key not found",
"http_status": 404
}
PHP Versions
Get available PHP versions for Vector environments.
List PHP Versions
Retrieves a list of all available PHP versions for Vector environments.
Currently supported versions: 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/php-versions" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$versions = $client->phpVersions->list();
const phpVersions = await client.phpVersions.list();
Response
{
"data": [
{
"value": "7.2",
"label": "PHP 7.2"
},
{
"value": "7.3",
"label": "PHP 7.3"
},
{
"value": "7.4",
"label": "PHP 7.4"
},
{
"value": "8.0",
"label": "PHP 8.0"
},
{
"value": "8.1",
"label": "PHP 8.1"
},
{
"value": "8.2",
"label": "PHP 8.2"
},
{
"value": "8.3",
"label": "PHP 8.3"
},
{
"value": "8.4",
"label": "PHP 8.4"
},
{
"value": "8.5",
"label": "PHP 8.5"
}
],
"message": "PHP versions retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
Sites
Manage serverless WordPress sites deployed on Vector infrastructure. Sites are the primary resource representing customer applications, each with associated environments (staging/production), deployments, and CDN configurations.
Sites are created with a pending status and transition to active once provisioning
completes. You can suspend sites to reduce costs during low-traffic periods.
Site Status Lifecycle
pending- Site creation initiated, provisioning in progressactive- Site is fully operational and serving trafficsuspended- Site is paused to reduce costs (can be unsuspended)terminating- Site deletion in progressterminated- Site has been fully removed
List Sites
Retrieves a paginated list of all sites for the authenticated account. Results include each site’s environments and their associated domains.
Use search to filter by customer ID or subdomain, status to filter by
site lifecycle state, and sort/direction to control ordering. The
last_deployed_at field is computed from the most recent completed
deployment across all environments and can also be used as a sort field.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
search
optional
|
string |
Search by Example:
"acme" |
|
status
optional
|
string |
Filter by site status. Must be one of: Example:
"active" |
|
sort
optional
|
string |
Sort results by the given field. Must be one of: Example:
"your_customer_id" |
|
direction
optional
|
string |
Sort direction. Must be Example:
"asc" |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites?per_page=25&search=acme&status=active&sort=your_customer_id&direction=asc&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$sites = $client->sites->list([
'per_page' => 25,
'search' => 'acme',
'status' => 'active',
'sort' => 'your_customer_id',
'direction' => 'asc',
'page' => 1,
]);
const sites = await client.sites.list({
per_page: 25,
search: 'acme',
status: 'active',
sort: 'your_customer_id',
direction: 'asc',
page: 1,
});
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"status": "active",
"status_label": "Active",
"dev_php_version": "8.3",
"tags": [
"wordpress",
"production"
],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_host": "dev-cluster.abc123.us-east-1.rds.amazonaws.com",
"dev_db_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"dev_sftp": {
"hostname": "ssh.vectorpages.com",
"port": 22,
"username": "wispy-dust"
},
"last_deployed_at": "2025-06-10T14:30:00+00:00",
"environments": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"php_version": "8.3",
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"custom_domain_certificate_status": "issued",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Sites retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"status": [
"The status must be a valid site status."
]
},
"message": "Validation failed",
"http_status": 422
}
Get Site
Retrieves details of a specific site including its environments and domains.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$site = $client->sites->get('01jfgxk4nqrst5vwx9yz0abcde');
const site = await client.sites.get('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"status": "active",
"status_label": "Active",
"tags": [
"wordpress",
"production"
],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_host": "dev-cluster.abc123.us-east-1.rds.amazonaws.com",
"dev_db_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"environments": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"php_version": "8.3",
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"custom_domain_certificate_status": "issued",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Site retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Create Site
Creates a new site for the authenticated account. The site is created with a
pending status and will transition to active once provisioning completes.
A development container is automatically provisioned for the site, accessible
via the dev_domain in the response.
Body Parameters
| Name | Type | Description |
|---|---|---|
|
your_customer_id
required
|
string |
Your internal customer identifier. Used to correlate sites with your billing or CRM system. Example:
"cust_12345" |
|
dev_php_version
required
|
string |
The PHP version for the development container. Must be one of: 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5. Example:
"8.3" |
|
tags
optional
|
string[] |
Optional array of tags for categorizing the site. Each tag must be slug format (lowercase letters, numbers, hyphens), max 100 characters, and unique. Example:
["wordpress","production"] |
|
production_domain
optional
|
string |
Optional custom domain for the production environment. Must be a valid fully qualified domain name, max 253 chars. When provided, SSL certificate provisioning begins automatically. The domain owner must create DNS records to complete provisioning — see the Example:
"example.com" |
|
staging_domain
optional
|
string |
Optional custom domain for the staging environment. Must be a valid fully qualified domain name, max 253 chars. When provided, SSL certificate provisioning begins automatically. The domain owner must create DNS records to complete provisioning — see the Example:
"staging.example.com" |
|
wp_admin_email
optional
|
string |
Optional email address for WordPress auto-install. When provided, WordPress will be automatically installed in the dev container on first boot. The Example:
"[email protected]" |
|
wp_admin_user
optional
|
string |
Optional WordPress admin username. Only used when Example:
"myadmin" |
|
wp_site_title
optional
|
string |
Optional WordPress site title. Only used when Example:
"My Blog" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"your_customer_id":"cust_12345","dev_php_version":"8.3","tags":["wordpress","production"],"production_domain":"example.com","staging_domain":"staging.example.com","wp_admin_email":"[email protected]","wp_admin_user":"myadmin","wp_site_title":"My Blog"}'
$site = $client->sites->create([
'your_customer_id' => 'cust_12345',
'dev_php_version' => '8.3',
'tags' => ['wordpress', 'production'],
'production_domain' => 'example.com',
'staging_domain' => 'staging.example.com',
'wp_admin_email' => '[email protected]',
'wp_admin_user' => 'myadmin',
'wp_site_title' => 'My Blog',
]);
const site = await client.sites.create({
your_customer_id: 'cust_12345',
dev_php_version: '8.3',
tags: ['wordpress', 'production'],
production_domain: 'example.com',
staging_domain: 'staging.example.com',
wp_admin_email: '[email protected]',
wp_admin_user: 'myadmin',
wp_site_title: 'My Blog',
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"status": "pending",
"status_label": "Pending",
"dev_php_version": "8.3",
"tags": [
"wordpress",
"production"
],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_host": "dev-cluster.abc123.us-east-1.rds.amazonaws.com",
"dev_db_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"dev_sftp": {
"hostname": "ssh.vectorpages.com",
"port": 22,
"username": "wispy-dust",
"password": "aBcD1234!@#$EfGh5678"
},
"dev_db_username": "db_01jfgxk4nqrst5vwx9yz0abcde",
"dev_db_password": "aBcD1234!@#$EfGh5678",
"wp_admin": {
"user": "myadmin",
"email": "[email protected]",
"password": "xYz9876!@#$AbCd5432",
"site_title": "My Blog"
},
"environments": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"name": "production",
"is_production": true,
"status": "pending",
"status_label": "Pending",
"php_version": "8.3",
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"custom_domain_certificate_status": "pending",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
{
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"name": "staging",
"is_production": false,
"status": "pending",
"status_label": "Pending",
"php_version": "8.3",
"platform_domain": "wispy-dust--staging.vectorpages.com",
"custom_domain": null,
"custom_domain_certificate_status": null,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Vector site creation initiated",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"your_customer_id": [
"The partner customer id field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"errors": {
"cluster": [
"No Vector cluster is configured for your account."
]
},
"message": "No Vector cluster available for this account",
"http_status": 422
}
Update Site
Updates an existing site’s metadata. Only the fields provided will be updated.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
your_customer_id
optional
|
string |
Your internal customer identifier. Example:
"cust_67890" |
|
tags
optional
|
string[] |
Array of tags for categorizing the site. Each tag must be slug format (lowercase letters, numbers, hyphens), max 100 characters, and unique. Pass Example:
["wordpress","staging"] |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"your_customer_id":"cust_67890","tags":["wordpress","staging"]}'
$site = $client->sites->update(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'your_customer_id' => 'cust_67890',
'tags' => ['wordpress', 'staging'],
]
);
const site = await client.sites.update(
'01jfgxk4nqrst5vwx9yz0abcde',
{
your_customer_id: 'cust_67890',
tags: ['wordpress', 'staging'],
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_67890",
"status": "active",
"status_label": "Active",
"tags": [
"wordpress",
"staging"
],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_host": "dev-cluster.abc123.us-east-1.rds.amazonaws.com",
"dev_db_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Vector site updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"tags": [
"Tags must be an array of strings."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Site
Initiates deletion of a site. This terminates the site’s development container
and CDN resources. The site status transitions to terminating and eventually
terminated.
Important: By default, all environments must be terminated before the site
can be deleted — use the environment delete endpoint to terminate each
environment first, or pass delete_environments: true to have any remaining
deployed environments terminated inline as part of the site deletion job.
This operation is irreversible. All site data and configurations will be permanently removed.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
delete_environments
optional
|
boolean |
Optional. When true, any remaining deployed environments are terminated as part of the site deletion job (each environment is terminated in sequence before the dev container and Ymir project are removed). When omitted or false, the request is rejected with 422 if deployed environments still exist. Example:
true |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->delete('01jfgxk4nqrst5vwx9yz0abcde');
const response = await client.sites.delete('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"status": "termination_requested",
"status_label": "Termination Requested",
"tags": [],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_host": "dev-cluster.abc123.us-east-1.rds.amazonaws.com",
"dev_db_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Vector site deletion initiated",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"site": [
"Cannot delete site with deployed environments. Please terminate all deployed environments first, or pass delete_environments=true to terminate them as part of the site deletion."
]
},
"message": "Cannot delete site with deployed environments. Please terminate all deployed environments first, or pass delete_environments=true to terminate them as part of the site deletion.",
"http_status": 422
}
Clone Site
Creates a new site by cloning an existing site’s development container, including files and database. Only the development container is cloned; production and staging environments are not copied. The new site is created with fresh, empty environments.
This workflow is useful for testing larger redesigns or refactors in isolation while still allowing maintenance of the original site. The cloned site operates independently, so changes to one do not affect the other.
The new site inherits attributes from the source site unless overridden in
the request. The cloned site is created with a pending status and will
transition to active once the clone operation completes.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The source site ID to clone from. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
your_customer_id
optional
|
string |
Optional customer identifier. Inherits from source if not provided. Example:
"cust_12345" |
|
dev_php_version
optional
|
string |
Optional PHP version. Inherits from source if not provided. Example:
"8.3" |
|
tags
optional
|
string[] |
Optional tags. Inherits from source if not provided. Example:
["wordpress","clone"] |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/clone" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"your_customer_id":"cust_12345","dev_php_version":"8.3","tags":["wordpress","clone"]}'
$site = $client->sites->clone(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'your_customer_id' => 'cust_12345',
'dev_php_version' => '8.3',
'tags' => ['wordpress', 'clone'],
]
);
const site = await client.sites.clone(
'01jfgxk4nqrst5vwx9yz0abcde',
{
your_customer_id: 'cust_12345',
dev_php_version: '8.3',
tags: ['wordpress', 'clone'],
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"your_customer_id": "cust_12345",
"status": "pending",
"status_label": "Pending",
"tags": [
"wordpress",
"clone"
],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_username": "db_01jfgxk4nqrst5vwx9yz0abcdf",
"dev_db_password": "aBcD1234!@#$EfGh5678",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Vector site clone initiated",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"site": [
"Source site must be in active state to clone."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"errors": {
"site": [
"Source site must have a dev container to clone."
]
},
"message": "Validation failed",
"http_status": 422
}
Suspend Site
Suspends a site’s development container by scaling the ECS service to zero. This reduces costs during low-traffic periods while preserving container resources for quick resumption.
The site must be in active status to be suspended. Suspended sites can be
resumed using the unsuspend endpoint.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X PUT \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/suspend" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $vectorPro
->sites.suspend
->put('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.suspend
.put('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"status": "suspended",
"status_label": "Suspended",
"tags": [],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Vector site suspension initiated",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"status": [
"Site cannot be suspended from current state 'pending'. Site must be 'active' to be suspended."
]
},
"message": "Site cannot be suspended from current state 'pending'. Site must be 'active' to be suspended.",
"http_status": 422
}
Unsuspend Site
Resumes a previously suspended site’s development container by scaling the
ECS service back to one. The site must be in suspended status to be unsuspended.
After unsuspension, the site transitions back to active status and resumes
serving traffic.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X PUT \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/unsuspend" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $vectorPro
->sites.unsuspend
->put('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.unsuspend
.put('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"status": "active",
"status_label": "Active",
"tags": [],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Vector site unsuspension initiated",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"status": [
"Site cannot be unsuspended from current state 'active'. Site must be 'suspended' to be unsuspended."
]
},
"message": "Site cannot be unsuspended from current state 'active'. Site must be 'suspended' to be unsuspended.",
"http_status": 422
}
CDN
Purge CDN cache for a site. Supports full cache purge, purge by cache tag, or purge of specific URLs.
Purge Cache
Purges the CDN cache for a site. Can purge the entire cache, by cache tag, or a specific URL.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
cache_tag
optional
|
string |
Purge only content with this cache tag. Example:
"images" |
|
url
optional
|
string |
Purge a specific URL. Example:
"https://example.com/style.css" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/purge-cache" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"cache_tag":"images","url":"https://example.com/style.css"}'
$response = $client->sites->purgeCache(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'cache_tag' => 'images',
'url' => 'https://example.com/style.css',
]
);
const response = await client.sites.purgeCache('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {},
"message": "Cache purged successfully",
"http_status": 200
}
{
"data": {
"cache_tag": "images"
},
"message": "Cache purged successfully for tag: images",
"http_status": 200
}
{
"data": {
"url": "https://example.com/style.css"
},
"message": "URL purged successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"url": [
"The url field must be a valid URL."
]
},
"message": "Validation failed",
"http_status": 422
}
CDN: Caching
Manage CDN caching configuration including smart cache, vary headers, origin shield, request coalescing, and stale content settings.
Get Caching Settings
Retrieves the current CDN caching configuration for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/caching" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.cdn.caching
->get('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.cdn.caching
.get('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"enable_smart_cache": true,
"cache_control_max_age_override": 2592000,
"cache_control_public_max_age_override": 0,
"disable_cookies": true,
"cache_error_responses": false,
"enable_query_string_ordering": true,
"ignore_query_strings": false,
"query_string_vary_parameters": [],
"enable_hostname_vary": false,
"enable_mobile_vary": false,
"enable_webp_vary": true,
"enable_avif_vary": true,
"enable_country_code_vary": false,
"enable_cookie_vary": false,
"cookie_vary_parameters": [],
"enable_origin_shield": false,
"origin_shield_zone_code": "",
"origin_shield_enable_concurrency_limit": false,
"origin_shield_max_concurrent_requests": 5000,
"origin_shield_queue_max_wait_time": 30,
"origin_shield_max_queued_requests": 1000,
"enable_request_coalescing": false,
"request_coalescing_timeout": 30,
"use_stale_while_updating": true,
"use_stale_while_offline": true,
"use_background_update": true,
"enable_cache_slice": false
},
"message": "Caching settings retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Update Caching Settings
Updates CDN caching configuration for a site. All fields are optional — only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
enable_smart_cache
optional
|
boolean |
Enable smart cache. Example:
true |
|
cache_control_max_age_override
optional
|
integer |
Server cache expiration in seconds. Use -1 to respect origin headers. Example:
2592000 |
|
cache_control_public_max_age_override
optional
|
integer |
Browser cache expiration in seconds. Example:
0 |
|
disable_cookies
optional
|
boolean |
Automatically strip cookies from responses. Example:
true |
|
cache_error_responses
optional
|
boolean |
Cache error responses from origin. |
|
enable_query_string_ordering
optional
|
boolean |
Sort query string parameters for better cache hit rates. Example:
true |
|
ignore_query_strings
optional
|
boolean |
Ignore query strings when serving cached objects. |
|
query_string_vary_parameters
optional
|
string[] |
Query string parameters to vary cache by. Example:
["utm_source","ref"] |
|
enable_hostname_vary
optional
|
boolean |
Vary cache by hostname. |
|
enable_mobile_vary
optional
|
boolean |
Vary cache by device type (mobile/desktop). |
|
enable_webp_vary
optional
|
boolean |
Vary cache by WebP support. Example:
true |
|
enable_avif_vary
optional
|
boolean |
Vary cache by AVIF support. Example:
true |
|
enable_country_code_vary
optional
|
boolean |
Vary cache by country code. |
|
enable_cookie_vary
optional
|
boolean |
Vary cache by cookie values. |
|
cookie_vary_parameters
optional
|
string[] |
Cookie names to vary cache by. Example:
["wordpress_logged_in"] |
|
enable_origin_shield
optional
|
boolean |
Enable origin shield. |
|
origin_shield_zone_code
optional
|
string |
Origin shield zone code (e.g., “FR”, “NY”). Example:
"FR" |
|
origin_shield_enable_concurrency_limit
optional
|
boolean |
Enable origin shield concurrency limit. |
|
origin_shield_max_concurrent_requests
optional
|
integer |
Max concurrent requests to origin (1-10000). Example:
5000 |
|
origin_shield_queue_max_wait_time
optional
|
integer |
Max queue wait time in seconds. Example:
30 |
|
origin_shield_max_queued_requests
optional
|
integer |
Max queued origin requests (0-30000). Example:
1000 |
|
enable_request_coalescing
optional
|
boolean |
Enable request coalescing. |
|
request_coalescing_timeout
optional
|
integer |
Request coalescing lock time in seconds. Example:
30 |
|
use_stale_while_updating
optional
|
boolean |
Serve stale content while cache is updating. Example:
true |
|
use_stale_while_offline
optional
|
boolean |
Serve stale content while origin is offline. Example:
true |
|
use_background_update
optional
|
boolean |
Update cache in background. Example:
true |
|
enable_cache_slice
optional
|
boolean |
Enable cache slicing (optimize for video). |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/caching" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"enable_smart_cache":true,"cache_control_max_age_override":2592000,"cache_control_public_max_age_override":0,"disable_cookies":true,"cache_error_responses":false,"enable_query_string_ordering":true,"ignore_query_strings":false,"query_string_vary_parameters":["utm_source","ref"],"enable_hostname_vary":false,"enable_mobile_vary":false,"enable_webp_vary":true,"enable_avif_vary":true,"enable_country_code_vary":false,"enable_cookie_vary":false,"cookie_vary_parameters":["wordpress_logged_in"],"enable_origin_shield":false,"origin_shield_zone_code":"FR","origin_shield_enable_concurrency_limit":false,"origin_shield_max_concurrent_requests":5000,"origin_shield_queue_max_wait_time":30,"origin_shield_max_queued_requests":1000,"enable_request_coalescing":false,"request_coalescing_timeout":30,"use_stale_while_updating":true,"use_stale_while_offline":true,"use_background_update":true,"enable_cache_slice":false}'
$response = $vectorPro
->sites.cdn.caching
->put('01jfgxk4nqrst5vwx9yz0abcde', [
'enable_smart_cache' => true,
'cache_control_max_age_override' => 2592000,
'cache_control_public_max_age_override' => 0,
'disable_cookies' => true,
'cache_error_responses' => false,
'enable_query_string_ordering' => true,
'ignore_query_strings' => false,
'query_string_vary_parameters' => ['utm_source', 'ref'],
'enable_hostname_vary' => false,
'enable_mobile_vary' => false,
'enable_webp_vary' => true,
'enable_avif_vary' => true,
'enable_country_code_vary' => false,
'enable_cookie_vary' => false,
'cookie_vary_parameters' => ['wordpress_logged_in'],
'enable_origin_shield' => false,
'origin_shield_zone_code' => 'FR',
'origin_shield_enable_concurrency_limit' => false,
'origin_shield_max_concurrent_requests' => 5000,
'origin_shield_queue_max_wait_time' => 30,
'origin_shield_max_queued_requests' => 1000,
'enable_request_coalescing' => false,
'request_coalescing_timeout' => 30,
'use_stale_while_updating' => true,
'use_stale_while_offline' => true,
'use_background_update' => true,
'enable_cache_slice' => false,
]);
const response = await vectorPro
.sites.cdn.caching
.put('01jfgxk4nqrst5vwx9yz0abcde', {
enable_smart_cache: true,
cache_control_max_age_override: 2592000,
cache_control_public_max_age_override: 0,
disable_cookies: true,
cache_error_responses: false,
enable_query_string_ordering: true,
ignore_query_strings: false,
query_string_vary_parameters: ['utm_source', 'ref'],
enable_hostname_vary: false,
enable_mobile_vary: false,
enable_webp_vary: true,
enable_avif_vary: true,
enable_country_code_vary: false,
enable_cookie_vary: false,
cookie_vary_parameters: ['wordpress_logged_in'],
enable_origin_shield: false,
origin_shield_zone_code: 'FR',
origin_shield_enable_concurrency_limit: false,
origin_shield_max_concurrent_requests: 5000,
origin_shield_queue_max_wait_time: 30,
origin_shield_max_queued_requests: 1000,
enable_request_coalescing: false,
request_coalescing_timeout: 30,
use_stale_while_updating: true,
use_stale_while_offline: true,
use_background_update: true,
enable_cache_slice: false,
});
Response
{
"data": {
"enable_smart_cache": true,
"cache_control_max_age_override": 2592000,
"disable_cookies": true
},
"message": "Caching settings updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"origin_shield_max_concurrent_requests": [
"The max concurrent requests must not exceed 10,000."
]
},
"message": "Validation failed",
"http_status": 422
}
CDN: Edge Rules
Manage CDN edge rules for request/response manipulation, redirects, caching overrides, and security controls.
Each edge rule defines:
- Action: What to do when triggered (redirect, set header, block, override cache, etc.)
- Triggers: Conditions to match against (URL, headers, country, IP, cookies, etc.)
- Extra Actions: Additional actions to perform alongside the primary action
List Edge Rules
Retrieves all edge rules configured for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/edge-rules" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.cdn.edgeRules
->get('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.cdn.edgeRules
.get('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": [
{
"guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"description": "Force SSL",
"enabled": true,
"action_type": "force-ssl",
"action_parameter_1": null,
"action_parameter_2": null,
"trigger_matching_type": "match-any",
"triggers": [
{
"type": "url",
"pattern_matching_type": "match-any",
"pattern_matches": [
"*"
],
"parameter_1": null
}
],
"extra_actions": []
}
],
"message": "Edge rules retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Get Edge Rule
Retrieves a specific edge rule by GUID.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
rule
required
|
string |
Example:
"architecto" |
|
ruleId
required
|
string |
The edge rule GUID. Example:
"a1b2c3d4-e5f6-7890-abcd-ef1234567890" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/edge-rules/architecto" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.cdn.edgeRules
->get('01jfgxk4nqrst5vwx9yz0abcde', 'architecto', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890');
const response = await vectorPro
.sites.cdn.edgeRules
.get('01jfgxk4nqrst5vwx9yz0abcde', 'architecto', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890');
Response
{
"data": {
"guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"description": "Force SSL",
"enabled": true,
"action_type": "force-ssl",
"action_parameter_1": null,
"action_parameter_2": null,
"trigger_matching_type": "match-any",
"triggers": [
{
"type": "url",
"pattern_matching_type": "match-any",
"pattern_matches": [
"*"
],
"parameter_1": null
}
],
"extra_actions": []
},
"message": "Edge rule retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Edge rule not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Create Edge Rule
Creates a new edge rule for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
description
required
|
string |
The rule description (max 255 characters). Example:
"Force SSL on all requests" |
|
enabled
optional
|
boolean |
Whether the rule is enabled. Defaults to true. Example:
true |
|
action_type
required
|
string |
The primary action type. Must be a valid edge rule action type (e.g., force-ssl, redirect, set-response-header, block-request, override-cache-time). Example:
"force-ssl" |
|
action_parameter_1
optional
|
string |
Action parameter 1 (usage depends on action type). Example:
"https://example.com/" |
|
action_parameter_2
optional
|
string |
Action parameter 2 (usage depends on action type). Example:
"architecto" |
|
trigger_matching_type
required
|
string |
How triggers are combined. Must be match-any, match-all, or match-none. Example:
"match-any" |
|
triggers
required
|
object[] |
At least one trigger condition. Example:
[{"type":"url","pattern_matching_type":"match-any","pattern_matches":["*"]}] |
|
extra_actions
optional
|
object[] |
Additional actions to perform. Example:
[[]] |
|
triggers[].type
required
|
string |
The trigger type. Example:
"url" |
|
triggers[].pattern_matching_type
required
|
string |
How patterns are matched. Example:
"match-any" |
|
triggers[].pattern_matches
required
|
string[] |
Patterns to match against. Example:
["*"] |
|
triggers[].parameter_1
optional
|
string |
Optional trigger parameter. Example:
"architecto" |
|
extra_actions[].action_type
required
|
string |
The extra action type. Example:
"set-response-header" |
|
extra_actions[].action_parameter_1
optional
|
string |
Action parameter 1. Example:
"X-Custom-Header" |
|
extra_actions[].action_parameter_2
optional
|
string |
Action parameter 2. Example:
"custom-value" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/edge-rules" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"description":"Force SSL on all requests","enabled":true,"action_type":"force-ssl","action_parameter_1":"https://example.com/","action_parameter_2":"architecto","trigger_matching_type":"match-any","triggers":[{"type":"url","pattern_matching_type":"match-any","pattern_matches":["*"]}],"extra_actions":[{"action_type":"set-response-header","action_parameter_1":"X-Custom-Header","action_parameter_2":"custom-value"}]}'
$response = $vectorPro
->sites.cdn.edgeRules
->post('01jfgxk4nqrst5vwx9yz0abcde', [
'description' => 'Force SSL on all requests',
'enabled' => true,
'action_type' => 'force-ssl',
'action_parameter_1' => 'https://example.com/',
'action_parameter_2' => 'architecto',
'trigger_matching_type' => 'match-any',
'triggers' => [[
'type' => 'url',
'pattern_matching_type' => 'match-any',
'pattern_matches' => ['*'],
]],
'extra_actions' => [[
'action_type' => 'set-response-header',
'action_parameter_1' => 'X-Custom-Header',
'action_parameter_2' => 'custom-value',
]],
]);
const response = await vectorPro
.sites.cdn.edgeRules
.post('01jfgxk4nqrst5vwx9yz0abcde', {
description: 'Force SSL on all requests',
enabled: true,
action_type: 'force-ssl',
action_parameter_1: 'https://example.com/',
action_parameter_2: 'architecto',
trigger_matching_type: 'match-any',
triggers: [{
type: 'url',
pattern_matching_type: 'match-any',
pattern_matches: ['*'],
}],
extra_actions: [{
action_type: 'set-response-header',
action_parameter_1: 'X-Custom-Header',
action_parameter_2: 'custom-value',
}],
});
Response
{
"data": {
"guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"description": "Force SSL on all requests",
"enabled": true,
"action_type": "force-ssl",
"action_parameter_1": null,
"action_parameter_2": null,
"trigger_matching_type": "match-any",
"triggers": [
{
"type": "url",
"pattern_matching_type": "match-any",
"pattern_matches": [
"*"
],
"parameter_1": null
}
],
"extra_actions": []
},
"message": "Edge rule created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"action_type": [
"The action type must be a valid edge rule action type."
],
"triggers": [
"The triggers field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Update Edge Rule
Updates an existing edge rule. All fields are optional — only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
rule
required
|
string |
Example:
"architecto" |
|
ruleId
required
|
string |
The edge rule GUID. Example:
"a1b2c3d4-e5f6-7890-abcd-ef1234567890" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
description
optional
|
string |
The rule description (max 255 characters). Example:
"Updated description" |
|
enabled
optional
|
boolean |
Whether the rule is enabled. |
|
action_type
optional
|
string |
The primary action type. Example:
"redirect" |
|
action_parameter_1
optional
|
string |
Action parameter 1. Example:
"https://example.com/new-location" |
|
action_parameter_2
optional
|
string |
Action parameter 2. Example:
"architecto" |
|
trigger_matching_type
optional
|
string |
How triggers are combined. Must be match-any, match-all, or match-none. Example:
"match-all" |
|
triggers
optional
|
object[] |
Trigger conditions (replaces all existing triggers). Example:
[[]] |
|
extra_actions
optional
|
object[] |
Extra actions (replaces all existing extra actions). Example:
[[]] |
|
triggers[].type
required
|
string |
The trigger type. Example:
"url" |
|
triggers[].pattern_matching_type
required
|
string |
How patterns are matched. Example:
"match-any" |
|
triggers[].pattern_matches
required
|
string[] |
Patterns to match against. Example:
["/old-page"] |
|
triggers[].parameter_1
optional
|
string |
Optional trigger parameter. Example:
"architecto" |
|
extra_actions[].action_type
required
|
string |
The extra action type. Example:
"set-response-header" |
|
extra_actions[].action_parameter_1
optional
|
string |
Action parameter 1. Example:
"X-Redirect" |
|
extra_actions[].action_parameter_2
optional
|
string |
Action parameter 2. Example:
"true" |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/edge-rules/architecto" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"description":"Updated description","enabled":false,"action_type":"redirect","action_parameter_1":"https://example.com/new-location","action_parameter_2":"architecto","trigger_matching_type":"match-all","triggers":[{"type":"url","pattern_matching_type":"match-any","pattern_matches":["/old-page"],"parameter_1":"architecto"}],"extra_actions":[{"action_type":"set-response-header","action_parameter_1":"X-Redirect","action_parameter_2":"true"}]}'
$response = $vectorPro
->sites.cdn.edgeRules
->put('01jfgxk4nqrst5vwx9yz0abcde', 'architecto', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', [
'description' => 'Updated description',
'enabled' => false,
'action_type' => 'redirect',
'action_parameter_1' => 'https://example.com/new-location',
'action_parameter_2' => 'architecto',
'trigger_matching_type' => 'match-all',
'triggers' => [[
'type' => 'url',
'pattern_matching_type' => 'match-any',
'pattern_matches' => ['/old-page'],
'parameter_1' => 'architecto',
]],
'extra_actions' => [[
'action_type' => 'set-response-header',
'action_parameter_1' => 'X-Redirect',
'action_parameter_2' => 'true',
]],
]);
const response = await vectorPro
.sites.cdn.edgeRules
.put('01jfgxk4nqrst5vwx9yz0abcde', 'architecto', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', {
description: 'Updated description',
enabled: false,
action_type: 'redirect',
action_parameter_1: 'https://example.com/new-location',
action_parameter_2: 'architecto',
trigger_matching_type: 'match-all',
triggers: [{
type: 'url',
pattern_matching_type: 'match-any',
pattern_matches: ['/old-page'],
parameter_1: 'architecto',
}],
extra_actions: [{
action_type: 'set-response-header',
action_parameter_1: 'X-Redirect',
action_parameter_2: 'true',
}],
});
Response
{
"data": {
"guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"description": "Updated description",
"enabled": false,
"action_type": "redirect",
"action_parameter_1": "https://example.com/new-location",
"action_parameter_2": null,
"trigger_matching_type": "match-all",
"triggers": [
{
"type": "url",
"pattern_matching_type": "match-any",
"pattern_matches": [
"/old-page"
],
"parameter_1": null
}
],
"extra_actions": []
},
"message": "Edge rule updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"action_type": [
"The action type must be a valid edge rule action type."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Edge Rule
Permanently deletes an edge rule. This action cannot be undone.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
rule
required
|
string |
Example:
"architecto" |
|
ruleId
required
|
string |
The edge rule GUID. Example:
"a1b2c3d4-e5f6-7890-abcd-ef1234567890" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/edge-rules/architecto" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.cdn.edgeRules
->delete('01jfgxk4nqrst5vwx9yz0abcde', 'architecto', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890');
const response = await vectorPro
.sites.cdn.edgeRules
.delete('01jfgxk4nqrst5vwx9yz0abcde', 'architecto', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890');
Response
{
"data": {},
"message": "Edge rule deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
CDN: Optimizer
Manage CDN optimizer configuration including image optimization, asset minification, and quality settings.
Get Optimizer Settings
Retrieves the current CDN optimizer configuration for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/optimizer" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.cdn.optimizer
->get('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.cdn.optimizer
.get('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"optimizer_enabled": true,
"optimizer_enable_webp": true,
"optimizer_automatic_optimization_enabled": true,
"optimizer_enable_manipulation_engine": false,
"optimizer_watermark_enabled": false,
"optimizer_minify_css": true,
"optimizer_minify_javascript": true,
"optimizer_image_quality": 85,
"optimizer_mobile_image_quality": 70,
"optimizer_desktop_max_width": 1600,
"optimizer_mobile_max_width": 800
},
"message": "Optimizer settings retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Update Optimizer Settings
Updates CDN optimizer configuration for a site. All fields are optional — only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
optimizer_enabled
optional
|
boolean |
Enable Bunny Optimizer. Example:
true |
|
optimizer_enable_webp
optional
|
boolean |
Enable WebP image compression. Example:
true |
|
optimizer_automatic_optimization_enabled
optional
|
boolean |
Enable automatic smart image optimization. Example:
true |
|
optimizer_enable_manipulation_engine
optional
|
boolean |
Enable dynamic image processing engine. |
|
optimizer_watermark_enabled
optional
|
boolean |
Enable image watermarking. |
|
optimizer_minify_css
optional
|
boolean |
Enable CSS minification. Example:
true |
|
optimizer_minify_javascript
optional
|
boolean |
Enable JavaScript minification. Example:
true |
|
optimizer_image_quality
optional
|
integer |
Desktop image quality (1-100). Example:
85 |
|
optimizer_mobile_image_quality
optional
|
integer |
Mobile image quality (1-100). Example:
70 |
|
optimizer_desktop_max_width
optional
|
integer |
Max automatic image width for desktop (0-5000). Example:
1600 |
|
optimizer_mobile_max_width
optional
|
integer |
Max automatic image width for mobile (0-5000). Example:
800 |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/cdn/optimizer" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"optimizer_enabled":true,"optimizer_enable_webp":true,"optimizer_automatic_optimization_enabled":true,"optimizer_enable_manipulation_engine":false,"optimizer_watermark_enabled":false,"optimizer_minify_css":true,"optimizer_minify_javascript":true,"optimizer_image_quality":85,"optimizer_mobile_image_quality":70,"optimizer_desktop_max_width":1600,"optimizer_mobile_max_width":800}'
$response = $vectorPro
->sites.cdn.optimizer
->put('01jfgxk4nqrst5vwx9yz0abcde', [
'optimizer_enabled' => true,
'optimizer_enable_webp' => true,
'optimizer_automatic_optimization_enabled' => true,
'optimizer_enable_manipulation_engine' => false,
'optimizer_watermark_enabled' => false,
'optimizer_minify_css' => true,
'optimizer_minify_javascript' => true,
'optimizer_image_quality' => 85,
'optimizer_mobile_image_quality' => 70,
'optimizer_desktop_max_width' => 1600,
'optimizer_mobile_max_width' => 800,
]);
const response = await vectorPro
.sites.cdn.optimizer
.put('01jfgxk4nqrst5vwx9yz0abcde', {
optimizer_enabled: true,
optimizer_enable_webp: true,
optimizer_automatic_optimization_enabled: true,
optimizer_enable_manipulation_engine: false,
optimizer_watermark_enabled: false,
optimizer_minify_css: true,
optimizer_minify_javascript: true,
optimizer_image_quality: 85,
optimizer_mobile_image_quality: 70,
optimizer_desktop_max_width: 1600,
optimizer_mobile_max_width: 800,
});
Response
{
"data": {
"optimizer_enabled": true,
"optimizer_minify_css": true,
"optimizer_image_quality": 85
},
"message": "Optimizer settings updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"optimizer_image_quality": [
"The image quality must not exceed 100."
]
},
"message": "Validation failed",
"http_status": 422
}
Databases
Manage database credentials for the site’s development container. Each site has a dedicated MySQL database for local development with credentials that can be reset for security.
Create Export
Start a database export operation. Dispatches an async job to create the export and upload it to S3. Poll the status endpoint to check progress and retrieve the download URL when complete.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
format
optional
|
string |
Export format. Currently only “sql” is supported. Default: sql. Example:
"sql" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/db/export" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"format":"sql"}'
$exportStatus = $client->sites->db->createExport(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'format' => 'sql',
]
);
const exportSession = await client.sites.db.createExport(
'01jfgxk4nqrst5vwx9yz0abcde',
{
format: 'sql',
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "pending",
"status_label": "Pending",
"format": "sql",
"size_bytes": null,
"duration_ms": null,
"error_message": null,
"download_expires_at": null,
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": null,
"completed_at": null
},
"message": "Database export started",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"format": [
"The selected format is invalid."
]
},
"message": "Validation failed",
"http_status": 422
}
Get Export Status
Get the current status of a database export operation. If complete and not expired, includes a presigned download URL valid for 1 hour.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
export
required
|
string |
The export ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/db/exports/01jfgxk4nqrst5vwx9yz0abcdg" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$exportStatus = $client->sites->db->getExportStatus(
'01jfgxk4nqrst5vwx9yz0abcde',
'01jfgxk4nqrst5vwx9yz0abcdg'
);
const exportStatus = await client.sites.db.getExportStatus(
'01jfgxk4nqrst5vwx9yz0abcde',
'01jfgxk4nqrst5vwx9yz0abcdg'
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "completed",
"status_label": "Completed",
"format": "sql",
"size_bytes": 52428800,
"duration_ms": 30000,
"error_message": null,
"download_url": "https://s3.amazonaws.com/bucket/exports/01jfgxk4nqrst5vwx9yz0abcdg.sql?X-Amz-Expires=3600",
"download_expires_at": "2025-01-15T13:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": "2025-01-15T12:00:01+00:00",
"completed_at": "2025-01-15T12:00:31+00:00"
},
"message": "Export retrieved successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "processing",
"status_label": "Processing",
"format": "sql",
"size_bytes": null,
"duration_ms": null,
"error_message": null,
"download_expires_at": null,
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": "2025-01-15T12:00:01+00:00",
"completed_at": null
},
"message": "Export retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Export not found",
"http_status": 404
}
Reset Password
Generates a new database password for the site’s development container. The old password is immediately invalidated.
The new password is returned ONLY in this response. Store it securely—it cannot be retrieved again.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X POST \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/db/reset-password" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $vectorPro
->sites.db.resetPassword
->post('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.db.resetPassword
.post('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": null,
"status": "active",
"status_label": "Active",
"dev_php_version": "8.3",
"tags": [],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_db_username": "db_01jfgxk4nqrst5vwx9yz0abcde",
"dev_db_password": "aBcD1234!@#$EfGh5678",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Database password reset successfully. Store the new password securely - it will not be shown again.",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Deployments List deployments across all environments of a site.
List Site Deployments
Retrieves a paginated list of deployments across all non-terminated environments belonging to the given site, ordered by most recent first.
Optionally filter by environment name to narrow results to a single
environment (e.g. production or staging).
Deployments attached to terminated environments are always excluded,
even when an explicit environment filter matches one.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID or subdomain. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Query Parameters
| Name | Type | Description |
|---|---|---|
|
environment
optional
|
string |
Filter deployments to a specific environment by name. Example:
"production" |
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/deployments?environment=production&per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.deployments
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde', [
'environment' => 'production',
'per_page' => 25,
'page' => 1,
]);
const response = await vectorPro
.sites.deployments
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde', {
environment: 'production',
per_page: 25,
page: 1,
});
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"is_auto_deploy": false,
"status": "deployed",
"status_label": "Deployed",
"stdout": "Deployment output...",
"stderr": null,
"build_output": null,
"actor": "[email protected]",
"environment": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"php_version": "8.3",
"tags": [
"wordpress"
],
"fqdn": "example.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Deployments retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"per_page": [
"Maximum items per page is 100."
]
},
"message": "Validation failed",
"http_status": 422
}
Imports
Get Import Status
Get the current status of an archive import operation. If the import is still pending and not expired, includes fresh presigned upload URL(s).
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
import
required
|
string |
The import ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/imports/01jfgxk4nqrst5vwx9yz0abcdh" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.imports
->get('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdh');
const response = await vectorPro
.sites.imports
.get('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdh');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "pending",
"status_label": "Pending",
"scope": null,
"filename": "backup.sql.gz",
"content_length": 52428800,
"is_multipart": false,
"part_count": null,
"checksum": {
"provided_md5": "d41d8cd98f00b204e9800998ecf8427e",
"s3_etag": null
},
"metadata": null,
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": null,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"uploaded_at": null,
"started_at": null,
"completed_at": null,
"upload_url": "https://s3.amazonaws.com/bucket/imports/...",
"upload_expires_at": "2025-01-16T12:00:00+00:00"
},
"message": "Import retrieved successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "completed",
"status_label": "Completed",
"scope": "full",
"scope_label": "Full",
"filename": "backup.sql.gz",
"content_length": 52428800,
"is_multipart": false,
"part_count": null,
"checksum": {
"provided_md5": "d41d8cd98f00b204e9800998ecf8427e",
"s3_etag": "d41d8cd98f00b204e9800998ecf8427e"
},
"metadata": null,
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": 30000,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"uploaded_at": "2025-01-15T12:00:01+00:00",
"started_at": "2025-01-15T12:00:02+00:00",
"completed_at": "2025-01-15T12:00:32+00:00"
},
"message": "Import retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Import not found",
"http_status": 404
}
Create Import Session
Create an archive import session. Returns presigned S3 upload URL(s) that can be used to upload the archive file directly to storage.
The maximum file size is 50GB by default. Higher limits can be configured per-cluster on request.
For files larger than the multipart threshold (~100MB), returns multiple
presigned URLs (one per part) along with an upload_id. Parts are 100MB each,
so a 1GB file requires 10 parts. For smaller files, returns a single presigned
upload URL.
After uploading, call the “Run Import” endpoint to execute the import.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
scope
optional
|
string |
Example:
"database"
Enum:
database
|
|
filename
optional
|
string |
The archive filename. Example:
"backup.sql.gz" |
|
content_length
required
|
integer |
The file size in bytes. Example:
104857600 |
|
content_md5
optional
|
string |
The MD5 hash of the file (32 hex characters). Example:
"d41d8cd98f00b204e9800998ecf8427e" |
|
options
optional
|
object |
Import options. Example:
[] |
|
options.drop_tables
optional
|
boolean |
Drop existing tables before import. Default: true. Example:
true |
|
options.disable_foreign_keys
optional
|
boolean |
Disable foreign key checks during import. Default: true. Example:
true |
|
options.search_replace
optional
|
object |
Search and replace configuration. Example:
[] |
|
options.search_replace.from
optional
|
string |
The value to search for. Example:
"example.org" |
|
options.search_replace.to
optional
|
string |
The replacement value. Example:
"example.com" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/imports" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"scope":"database","filename":"backup.sql.gz","content_length":104857600,"content_md5":"d41d8cd98f00b204e9800998ecf8427e","options":{"drop_tables":true,"disable_foreign_keys":true,"search_replace":{"from":"example.org","to":"example.com"}}}'
$response = $vectorPro
->sites.imports
->post('01jfgxk4nqrst5vwx9yz0abcde', [
'scope' => 'database',
'filename' => 'backup.sql.gz',
'content_length' => 104857600,
'content_md5' => 'd41d8cd98f00b204e9800998ecf8427e',
'options' => [
'drop_tables' => true,
'disable_foreign_keys' => true,
'search_replace' => [
'from' => 'example.org',
'to' => 'example.com',
],
],
]);
const response = await vectorPro
.sites.imports
.post('01jfgxk4nqrst5vwx9yz0abcde', {
scope: 'database',
filename: 'backup.sql.gz',
content_length: 104857600,
content_md5: 'd41d8cd98f00b204e9800998ecf8427e',
options: {
drop_tables: true,
disable_foreign_keys: true,
search_replace: {
from: 'example.org',
to: 'example.com',
},
},
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "pending",
"status_label": "Pending",
"scope": null,
"filename": "backup.sql.gz",
"content_length": 52428800,
"is_multipart": false,
"part_count": null,
"checksum": {
"provided_md5": "d41d8cd98f00b204e9800998ecf8427e",
"s3_etag": null
},
"metadata": null,
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": null,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"uploaded_at": null,
"started_at": null,
"completed_at": null,
"upload_url": "https://s3.amazonaws.com/bucket/imports/...",
"upload_expires_at": "2025-01-16T12:00:00+00:00"
},
"message": "Import session created successfully",
"http_status": 201
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "pending",
"status_label": "Pending",
"scope": null,
"filename": "backup.tar.gz",
"content_length": 161061273600,
"is_multipart": true,
"part_count": 30,
"checksum": {
"provided_md5": null,
"s3_etag": null
},
"metadata": null,
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": null,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"uploaded_at": null,
"started_at": null,
"completed_at": null,
"upload_id": "abc123",
"upload_parts": [
{
"part_number": 1,
"url": "https://s3.amazonaws.com/..."
}
],
"upload_expires_at": "2025-01-16T12:00:00+00:00"
},
"message": "Import session created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"site": [
"Site must be in active state to import."
]
},
"message": "Validation failed",
"http_status": 422
}
Run Import
Execute an archive import from S3 after the file has been uploaded via the presigned URL(s). Dispatches an async job to perform the import.
For multipart uploads, provide the parts array containing the
part_number and etag for each uploaded part. Each part can be up to
5GB. The server will finalize the multipart upload before starting the
import job.
The import must be in pending or uploaded status and not expired.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
import
required
|
string |
The import ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
parts
optional
|
string[] |
Multipart upload parts (required for multipart uploads). Example:
["architecto"] |
|
parts[].part_number
required
|
integer |
The part number. Example:
1 |
|
parts[].etag
required
|
string |
The ETag returned by S3 for this part. Example:
"\"d41d8cd98f00b204e9800998ecf8427e\"" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/imports/01jfgxk4nqrst5vwx9yz0abcdh/run" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"parts":["architecto"]}'
$response = $vectorPro
->sites.imports.run
->post('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdh', [
'parts' => ['architecto'],
]);
const response = await vectorPro
.sites.imports.run
.post('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdh', {
parts: ['architecto'],
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "uploaded",
"status_label": "Uploaded",
"scope": null,
"filename": "backup.sql.gz",
"content_length": 52428800,
"is_multipart": false,
"part_count": null,
"checksum": {
"provided_md5": "d41d8cd98f00b204e9800998ecf8427e",
"s3_etag": null
},
"metadata": null,
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": null,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"uploaded_at": "2025-01-15T12:00:01+00:00",
"started_at": null,
"completed_at": null
},
"message": "Archive import started",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Import not found",
"http_status": 404
}
{
"data": {},
"errors": {
"status": [
"Import must be in pending or uploaded status"
]
},
"message": "Import is not ready to run",
"http_status": 422
}
{
"data": {},
"errors": {
"expires_at": [
"Please create a new import session"
]
},
"message": "Import session has expired",
"http_status": 422
}
{
"data": {},
"errors": {
"parts": [
"Failed to complete multipart upload"
]
},
"message": "Failed to finalize upload",
"http_status": 422
}
Logs
Fetch logs for a Vector site. Supports filtering by time range, environment, deployment, and log level. Rate limited to 60 queries per hour per account.
Get Logs
Retrieves logs for the specified Vector site. Logs are returned in reverse chronological order (newest first).
Use the environment, deployment_id, and level filters to narrow down results.
Use cursor-based pagination for large result sets.
Rate limited to 60 queries per hour per account. Query time window is limited to 24 hours.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Query Parameters
| Name | Type | Description |
|---|---|---|
|
start_time
optional
|
string |
Start time for log query. RFC3339 format or relative (e.g., “now-1h”). Default: now-1h. Example:
"now-24h" |
|
end_time
optional
|
string |
End time for log query. RFC3339 format or relative. Default: now. Example:
"now" |
|
limit
optional
|
integer |
Maximum number of log entries to return (1-1000). Default: 100. Example:
500 |
|
environment
optional
|
string |
Filter by environment name (e.g., production, staging). Example:
"production" |
|
deployment_id
optional
|
string |
Filter by deployment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
|
level
optional
|
string |
Filter by log level (e.g., error, warning, info). Example:
"error" |
|
cursor
optional
|
string |
Pagination cursor from previous response. Example:
"abc123xyz" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/logs?start_time=now-24h&end_time=now&limit=500&environment=production&deployment_id=01jfgxk4nqrst5vwx9yz0abcdh&level=error&cursor=abc123xyz" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->getLogs(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'start_time' => 'now-24h',
'end_time' => 'now',
'limit' => 500,
'environment' => 'production',
'deployment_id' => '01jfgxk4nqrst5vwx9yz0abcdh',
'level' => 'error',
'cursor' => 'abc123xyz',
]
);
const logs = await client.sites.getLogs(
'01jfgxk4nqrst5vwx9yz0abcde',
{
start_time: 'now-24h',
end_time: 'now',
limit: 500,
environment: 'production',
deployment_id: '01jfgxk4nqrst5vwx9yz0abcdh',
level: 'error',
cursor: 'abc123xyz',
}
);
Response
{
"data": {
"logs": {
"tables": [
{
"name": "0",
"columns": [
{
"name": "_time",
"type": "datetime"
},
{
"name": "message",
"type": "string"
},
{
"name": "level",
"type": "string"
}
],
"rows": [
[
"2025-01-15T12:00:00+00:00",
"Request completed",
"info"
]
]
}
],
"status": {
"rowsExamined": 1000,
"rowsMatched": 50
}
},
"cursor": "abc123xyz",
"has_more": true
},
"message": "Logs retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"time_window": [
"The query time window cannot exceed 24 hours."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"message": "Too many log queries. Rate limit: 60 per hour.",
"http_status": 429
}
SFTP
Manage SFTP access to your site’s development container. SFTP provides secure file transfer for uploading themes, plugins, and other files directly to your dev environment.
Reset Password
Generates a new SFTP password for the site’s development container. The old password is immediately invalidated.
The new password is returned ONLY in this response. Store it securely—it cannot be retrieved again.
SFTP connection details:
- hostname: ssh.{partner-domain} (e.g., ssh.vectorpages.com)
- port: 22
- username: site subdomain (e.g., my-site)
- password: the generated password
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X POST \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/sftp/reset-password" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $client->sites->resetSftpPassword('01jfgxk4nqrst5vwx9yz0abcde');
const response = await client.sites.resetSftpPassword('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": null,
"status": "active",
"status_label": "Active",
"dev_php_version": "8.3",
"tags": [],
"dev_domain": "dev.wispy-dust.vectorpages.com",
"dev_sftp": {
"hostname": "ssh.vectorpages.com",
"port": 22,
"username": "wispy-dust",
"password": "aBcD1234!@#$EfGh5678"
},
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SFTP password reset successfully. Store the new password securely - it will not be shown again.",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
SSH Keys
Manage SSH keys installed on specific dev sites. These keys are actually deployed to the site’s container and grant SSH access.
When a new dev site is created, account-level default SSH keys are automatically copied to the site. Use these endpoints to manage keys on existing sites.
List SSH Keys
Retrieves all SSH keys installed on a specific dev site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcdi/ssh-keys?per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->sshKeys->list('01jfgxk4nqrst5vwx9yz0abcdi');
const sshKeys = await client.sites.sshKeys.list('01jfgxk4nqrst5vwx9yz0abcdi');
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"account_id": 1,
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcdj",
"name": "developer key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": false,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "SSH keys retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Add SSH Key
Adds a new SSH key to a specific dev site. The key will be deployed to the site’s container and grant SSH access.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
required
|
string |
A friendly name for the SSH key. Example:
"developer key" |
|
public_key
required
|
string |
The SSH public key in OpenSSH format. Example:
"ssh-rsa AAAAB3NzaC1yc2EA... user@host" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcdi/ssh-keys" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"developer key","public_key":"ssh-rsa AAAAB3NzaC1yc2EA... user@host"}'
$response = $client->sites->sshKeys->add(
'01jfgxk4nqrst5vwx9yz0abcdi',
[
'name' => 'developer key',
'public_key' => 'ssh-rsa AAAAB3NzaC1yc2EA... user@host',
]
);
const response = await client.sites.sshKeys.add(
'01jfgxk4nqrst5vwx9yz0abcdi',
{
name: 'developer key',
public_key: 'ssh-rsa AAAAB3NzaC1yc2EA... user@host',
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"account_id": 1,
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcdj",
"name": "developer key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": false,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSH key added to site successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"public_key": [
"Unable to parse SSH public key. Ensure it is in valid OpenSSH format."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"errors": {
"public_key": [
"This SSH key is already installed on this site."
]
},
"message": "Validation failed",
"http_status": 422
}
Remove SSH Key
Removes an SSH key from a specific dev site. The key will be removed from the site’s container and SSH access will be revoked.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
|
key
required
|
string |
The SSH key ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdk" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcdi/ssh-keys/01jfgxk4nqrst5vwx9yz0abcdk" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->sshKeys->remove(
'01jfgxk4nqrst5vwx9yz0abcdi',
'01jfgxk4nqrst5vwx9yz0abcdk'
);
const response = await client.sites.sshKeys.remove(
'01jfgxk4nqrst5vwx9yz0abcdi',
'01jfgxk4nqrst5vwx9yz0abcdk'
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdk",
"account_id": 1,
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcdj",
"name": "developer key",
"fingerprint": "SHA256:abc123def456...",
"public_key_preview": "ssh-rsa AAAAB3NzaC1yc2EA...user@host",
"is_account_default": false,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSH key removed from site successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "SSH key not found on this site",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
WAF: Access Lists
Manage WAF access lists including managed threat feeds and custom IP/CIDR/ASN/domain lists. Managed lists are curated threat intelligence feeds that can be enabled/disabled. Custom lists allow you to create your own allowlists or blocklists.
List Access Lists
Retrieves all access lists (managed and custom) for a site, including usage limits.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.accessLists
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.accessLists
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"managed_lists": [
{
"list_id": 1,
"configuration_id": 42,
"name": "TOR Exit Nodes",
"description": "Known TOR exit node IP addresses",
"is_enabled": true,
"type": 0,
"category": 32,
"action": 0,
"required_plan": 0,
"entry_count": 12345,
"update_frequency": "1.00:00:00",
"last_updated": "2026-04-01T00:00:00Z"
}
],
"custom_lists": [],
"custom_entry_count": 0,
"custom_entry_limit": 10000,
"custom_list_count": 0,
"custom_list_limit": 25
},
"message": "Access lists retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Get Custom Access List
Retrieves a single custom access list with its content.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
listId
required
|
integer |
The access list ID. Example:
1 |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists/1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.accessLists
->get('architecto', 1, '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.accessLists
.get('architecto', 1, '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": 1,
"name": "Office IPs",
"description": "Trusted office IP ranges",
"type": 0,
"content": "203.0.113.0/24\n198.51.100.1",
"checksum": "abc123",
"entry_count": 2,
"last_modified": "2026-04-01T00:00:00Z"
},
"message": "Custom access list retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Create Custom Access List
Creates a new custom access list with the provided entries.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
required
|
string |
The list name (max 255 characters). Example:
"Office IPs" |
|
description
optional
|
string |
A description of the list (max 1000 characters). Example:
"Trusted office IP ranges" |
|
type
required
|
integer |
The list type (0=IP, 1=CIDR, 2=ASN, 3=Country, 4=Domain, 5=Header). Example:
0 |
|
content
required
|
string |
Newline-separated list entries. Example:
"203.0.113.0/24\\n198.51.100.1" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"Office IPs","description":"Trusted office IP ranges","type":0,"content":"203.0.113.0/24\\n198.51.100.1"}'
$response = $vectorPro
->sites.waf.accessLists
->post('architecto', '01jfgxk4nqrst5vwx9yz0abcde', [
'name' => 'Office IPs',
'description' => 'Trusted office IP ranges',
'type' => 0,
'content' => '203.0.113.0/24\n198.51.100.1',
]);
const response = await vectorPro
.sites.waf.accessLists
.post('architecto', '01jfgxk4nqrst5vwx9yz0abcde', {
name: 'Office IPs',
description: 'Trusted office IP ranges',
type: 0,
content: '203.0.113.0/24\n198.51.100.1',
});
Response
{
"data": {
"id": 1,
"name": "Office IPs",
"description": "Trusted office IP ranges",
"type": 0,
"content": "203.0.113.0/24\n198.51.100.1",
"checksum": "abc123",
"entry_count": 2,
"last_modified": "2026-04-01T00:00:00Z"
},
"message": "Custom access list created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"name": [
"The name field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Update Custom Access List
Updates a custom access list’s name and/or content. Only include fields you want to change.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
listId
required
|
integer |
The access list ID. Example:
1 |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
optional
|
string |
The list name (max 255 characters). Example:
"Updated Office IPs" |
|
content
optional
|
string |
Newline-separated list entries. Example:
"203.0.113.0/24\\n198.51.100.1\\n10.0.0.0/8" |
Response Codes
Request
curl -X PATCH \
"https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists/1" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"Updated Office IPs","content":"203.0.113.0/24\\n198.51.100.1\\n10.0.0.0/8"}'
$response = $vectorPro
->sites.waf.accessLists
->patch('architecto', 1, '01jfgxk4nqrst5vwx9yz0abcde', [
'name' => 'Updated Office IPs',
'content' => '203.0.113.0/24\n198.51.100.1\n10.0.0.0/8',
]);
const response = await vectorPro
.sites.waf.accessLists
.patch('architecto', 1, '01jfgxk4nqrst5vwx9yz0abcde', {
name: 'Updated Office IPs',
content: '203.0.113.0/24\n198.51.100.1\n10.0.0.0/8',
});
Response
{
"data": {
"id": 1,
"name": "Updated Office IPs",
"description": "Trusted office IP ranges",
"type": 0,
"content": "203.0.113.0/24\n198.51.100.1\n10.0.0.0/8",
"checksum": "def456",
"entry_count": 3,
"last_modified": "2026-04-07T00:00:00Z"
},
"message": "Custom access list updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"name": [
"The name must be a string."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Custom Access List
Permanently deletes a custom access list. This action cannot be undone.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
listId
required
|
integer |
The access list ID. Example:
1 |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists/1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.accessLists
->delete('architecto', 1, '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.accessLists
.delete('architecto', 1, '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {},
"message": "Custom access list deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Update Access List Configuration
Updates the configuration (enable/disable and action) for any access list (managed or custom).
Use the configuration_id from the index response, not the list_id.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
configId
required
|
integer |
The access list configuration ID. Example:
42 |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
is_enabled
optional
|
boolean |
Whether the list is enabled. Example:
true |
|
action
optional
|
integer |
The action to take (0=Block, 1=Log, 2=Allow, 3=Challenge, 4=Captcha, 5=Bypass). Example:
0 |
Response Codes
Request
curl -X PATCH \
"https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists/configurations/42" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"is_enabled":true,"action":0}'
$response = $vectorPro
->sites.waf.accessLists.configurations
->patch('architecto', 42, '01jfgxk4nqrst5vwx9yz0abcde', [
'is_enabled' => true,
'action' => 0,
]);
const response = await vectorPro
.sites.waf.accessLists.configurations
.patch('architecto', 42, '01jfgxk4nqrst5vwx9yz0abcde', {
is_enabled: true,
action: 0,
});
Response
{
"data": {},
"message": "Access list configuration updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"action": [
"The action must be 0 (Block), 1 (Log), 2 (Allow), 3 (Challenge), 4 (Captcha), or 5 (Bypass)."
]
},
"message": "Validation failed",
"http_status": 422
}
Get Access List Enums
Retrieves available enum values for access list types, actions, and categories.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/access-lists/enums" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.accessLists.enums
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.accessLists.enums
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {},
"message": "Access list enums retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
WAF: Blocked IPs
Block specific IP addresses or CIDR ranges from accessing your site.
Blocked IPs receive a 403 Forbidden response.
- Single IPs:
192.0.2.1 - CIDR ranges:
198.51.100.0/24
List Blocked IPs
Retrieves all blocked IP addresses for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/blocked-ips" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->listBlockedIPs('01jfgxk4nqrst5vwx9yz0abcde');
const blockedIPs = await client.sites.waf.listBlockedIPs('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": [
{
"ip": "192.0.2.1"
},
{
"ip": "198.51.100.0/24"
}
],
"message": "Blocked IPs retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Add Blocked IP
Adds an IP address to the blocked list. Supports both IPv4 and IPv6 addresses.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
ip
required
|
string |
The IP address to block. Example:
"192.0.2.1" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/blocked-ips" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"ip":"192.0.2.1"}'
$response = $client->sites->waf->addBlockedIP(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'ip' => '192.0.2.1',
]
);
const response = await client.sites.waf.addBlockedIP(
'01jfgxk4nqrst5vwx9yz0abcde',
{
ip: '192.0.2.1',
}
);
Response
{
"data": {
"ip": "192.0.2.1"
},
"message": "Blocked IP added successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"ip": [
"The ip field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Remove Blocked IP
Removes an IP address from the blocked list.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
ip
required
|
string |
The IP address to remove. Example:
"192.0.2.1" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/blocked-ips/192.0.2.1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->removeBlockedIP(
'01jfgxk4nqrst5vwx9yz0abcde',
'192.0.2.1'
);
const response = await client.sites.waf.removeBlockedIP(
'01jfgxk4nqrst5vwx9yz0abcde',
'192.0.2.1'
);
Response
{
"data": {
"ip": "192.0.2.1"
},
"message": "Blocked IP removed successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Blocked IP not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
WAF: Bot Detection
Manage bot detection settings including execution mode, sensitivity levels, and browser fingerprint configuration.
Get Bot Detection Settings
Retrieves the current bot detection configuration for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/bot-detection" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.botDetection
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.botDetection
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"execution_mode": 1,
"request_integrity_sensitivity": 2,
"ip_address_sensitivity": 1,
"browser_fingerprint_sensitivity": 2,
"browser_fingerprint_aggression": 1,
"browser_fingerprint_complex_enabled": false
},
"message": "Bot detection settings retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Update Bot Detection Settings
Updates bot detection configuration for a site. All fields are optional — only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
execution_mode
optional
|
integer |
Execution mode (0=Off, 1=On). Example:
1 |
|
request_integrity_sensitivity
optional
|
integer |
Request integrity sensitivity (0=Off, 1=Low, 2=Medium, 3=High). Example:
2 |
|
ip_address_sensitivity
optional
|
integer |
IP address sensitivity (0=Off, 1=Low, 2=Medium, 3=High). Example:
1 |
|
browser_fingerprint_sensitivity
optional
|
integer |
Browser fingerprint sensitivity (0=Off, 1=Low, 2=Medium, 3=High). Example:
2 |
|
browser_fingerprint_aggression
optional
|
integer |
Browser fingerprint aggression (0=Off, 1=Low, 2=Medium, 3=High, 4=VeryHigh). Example:
1 |
|
browser_fingerprint_complex_enabled
optional
|
boolean |
Enable complex browser fingerprinting. |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/architecto/waf/bot-detection" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"execution_mode":1,"request_integrity_sensitivity":2,"ip_address_sensitivity":1,"browser_fingerprint_sensitivity":2,"browser_fingerprint_aggression":1,"browser_fingerprint_complex_enabled":false}'
$response = $vectorPro
->sites.waf.botDetection
->put('architecto', '01jfgxk4nqrst5vwx9yz0abcde', [
'execution_mode' => 1,
'request_integrity_sensitivity' => 2,
'ip_address_sensitivity' => 1,
'browser_fingerprint_sensitivity' => 2,
'browser_fingerprint_aggression' => 1,
'browser_fingerprint_complex_enabled' => false,
]);
const response = await vectorPro
.sites.waf.botDetection
.put('architecto', '01jfgxk4nqrst5vwx9yz0abcde', {
execution_mode: 1,
request_integrity_sensitivity: 2,
ip_address_sensitivity: 1,
browser_fingerprint_sensitivity: 2,
browser_fingerprint_aggression: 1,
browser_fingerprint_complex_enabled: false,
});
Response
{
"data": {
"execution_mode": 1,
"request_integrity_sensitivity": 2,
"ip_address_sensitivity": 1,
"browser_fingerprint_sensitivity": 2,
"browser_fingerprint_aggression": 1,
"browser_fingerprint_complex_enabled": false
},
"message": "Bot detection settings updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"execution_mode": [
"The execution mode must be 0 (Off) or 1 (On)."
]
},
"message": "Validation failed",
"http_status": 422
}
WAF: DDoS Protection
Manage DDoS protection settings including sensitivity, execution mode, and challenge window.
Get DDoS Protection Settings
Retrieves the current DDoS protection configuration for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/ddos" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.ddos
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.ddos
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"enabled": true,
"protection_type": 1,
"sensitivity": 2,
"execution_mode": 1,
"challenge_window": 30
},
"message": "DDoS protection settings retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Update DDoS Protection Settings
Updates DDoS protection configuration for a site. All fields are optional — only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
enabled
optional
|
boolean |
Enable or disable DDoS protection. Example:
true |
|
protection_type
optional
|
integer |
Protection type (0=DetectOnly, 1=ActiveStandard, 2=ActiveAggressive). Example:
1 |
|
sensitivity
optional
|
integer |
Shield sensitivity (0=Off, 1=Low, 2=Medium, 3=High, 4=VeryHigh). Example:
2 |
|
execution_mode
optional
|
integer |
Execution mode (0=Off, 1=On). Example:
1 |
|
challenge_window
optional
|
integer |
Challenge window in seconds. Example:
30 |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/architecto/waf/ddos" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"enabled":true,"protection_type":1,"sensitivity":2,"execution_mode":1,"challenge_window":30}'
$response = $vectorPro
->sites.waf.ddos
->put('architecto', '01jfgxk4nqrst5vwx9yz0abcde', [
'enabled' => true,
'protection_type' => 1,
'sensitivity' => 2,
'execution_mode' => 1,
'challenge_window' => 30,
]);
const response = await vectorPro
.sites.waf.ddos
.put('architecto', '01jfgxk4nqrst5vwx9yz0abcde', {
enabled: true,
protection_type: 1,
sensitivity: 2,
execution_mode: 1,
challenge_window: 30,
});
Response
{
"data": {
"enabled": true,
"protection_type": 1,
"sensitivity": 2,
"execution_mode": 1,
"challenge_window": 30
},
"message": "DDoS protection settings updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"sensitivity": [
"The sensitivity must be 0 (Off), 1 (Low), 2 (Medium), 3 (High), or 4 (VeryHigh)."
]
},
"message": "Validation failed",
"http_status": 422
}
WAF: Profiles
List available WAF profiles that can be assigned to a site.
List WAF Profiles
Retrieves the available WAF profiles that can be assigned to a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/profiles" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.profiles
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.profiles
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": [
{
"Id": 1,
"Name": "Default"
},
{
"Id": 2,
"Name": "WordPress"
}
],
"message": "WAF profiles retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
WAF: Rate Limits
Protect against DDoS, brute force, and API abuse by limiting request frequency.
Each rule defines:
- Threshold: Requests allowed within a time window
- Block Duration: How long to block offending clients (30s to 1 hour)
- Matching Criteria: Target specific paths, methods, or request patterns
Maximum 25 rate limit rules per site.
List Rate Limits
Retrieves all rate limit rules configured for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/rate-limits" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->listRateLimits('01jfgxk4nqrst5vwx9yz0abcde');
const rateLimits = await client.sites.waf.listRateLimits('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": [
{
"id": 12345,
"name": "API Rate Limit",
"description": "Limit API requests to 100/second",
"shield_zone_id": 67890,
"configuration": {
"request_count": 100,
"timeframe": 1,
"block_time": 60,
"value": "/api/*",
"action": "rate-limit",
"operator": "begins-with",
"variables": [
"request-uri"
],
"transformations": [
"lowercase"
]
}
}
],
"message": "Rate limits retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Get Rate Limit
Retrieves a specific rate limit rule by ID.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
rule
required
|
integer |
The rate limit rule ID. Example:
12345 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/rate-limits/12345" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->getRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
'12345'
);
const rateLimit = await client.sites.waf.getRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
'12345'
);
Response
{
"data": {
"id": 12345,
"name": "API Rate Limit",
"description": "Limit API requests to 100/second",
"shield_zone_id": 67890,
"configuration": {
"request_count": 100,
"timeframe": 1,
"block_time": 60,
"value": "/api/*",
"action": "rate-limit",
"operator": "begins-with",
"variables": [
"request-uri"
],
"transformations": [
"lowercase"
]
}
},
"message": "Rate limit retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Rate limit not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Create Rate Limit
Creates a new rate limit rule for a site. Maximum 25 rate limit rules per zone.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
required
|
string |
The rule name (max 255 characters). Example:
"API Rate Limit" |
|
description
optional
|
string |
The rule description (max 1000 characters). Example:
"Limit API requests to prevent abuse" |
|
request_count
required
|
integer |
Number of requests allowed within the timeframe. Must be between 1 and 1,000,000. Example:
100 |
|
timeframe
required
|
integer |
Time window for counting requests. Must be exactly 1 (per second) or 10 (per 10 seconds). Example:
1 |
|
block_time
required
|
integer |
Duration to block clients who exceed the limit, in seconds. Must be one of: 30, 60, 300, 900, 1800, 3600. Example:
60 |
|
value
optional
|
string |
URL path or pattern to match against. Max 2048 characters. Example:
"/api/*" |
|
operator
optional
|
string |
Match operator for comparing against the value. Must be one of: begins-with, ends-with, contains, contains-word, str-match, eq, ge, gt, le, lt, within, regex, str-eq, detect-sqli, detect-xss. Example:
"begins-with" |
|
transformations
optional
|
string[] |
Transformations to apply to variable values before matching. Each must be one of: cmdline, compress-whitespace, css-decode, hex-encode, html-entity-decode, js-decode, length, lowercase, md5, normalize-path, normalise-path, normalize-path-win, normalise-path-win, remove-comments, remove-nulls, remove-whitespace, replace-comments, sha1, url-decode, url-decode-uni, utf8-to-unicode. Example:
["lowercase","url-decode"] |
|
variables
optional
|
string[] |
Request variables to inspect when matching. Each must be one of: request-uri, request-uri-raw, args, args-combined-size, args-get, args-get-names, args-post, args-post-names, files-names, geo, remote-addr, query-string, request-basename, request-body, request-cookies-names, request-cookies, request-filename, request-headers-names, request-headers, request-line, request-method, request-protocol, response-body, response-headers, response-status. Example:
["request-uri"] |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/rate-limits" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"API Rate Limit","description":"Limit API requests to prevent abuse","request_count":100,"timeframe":1,"block_time":60,"value":"/api/*","operator":"begins-with","transformations":["lowercase","url-decode"],"variables":["request-uri"]}'
$response = $client->sites->waf->createRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'name' => 'API Rate Limit',
'description' => 'Limit API requests to prevent abuse',
'request_count' => 100,
'timeframe' => 1,
'block_time' => 60,
'value' => '/api/*',
'operator' => 'begins-with',
'transformations' => ['lowercase', 'url-decode'],
'variables' => ['request-uri'],
]
);
const rateLimit = await client.sites.waf.createRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
{
name: 'API Rate Limit',
description: 'Limit API requests to prevent abuse',
request_count: 100,
timeframe: 1,
block_time: 60,
value: '/api/*',
operator: 'begins-with',
transformations: ['lowercase', 'url-decode'],
variables: ['request-uri'],
}
);
Response
{
"data": {
"id": 12345,
"name": "API Rate Limit",
"description": "Limit API requests to prevent abuse",
"shield_zone_id": 67890,
"configuration": {
"request_count": 100,
"timeframe": 1,
"block_time": 60,
"value": "/api/*",
"action": "rate-limit",
"operator": "begins-with",
"variables": [
"request-uri"
],
"transformations": [
"lowercase",
"url-decode"
]
}
},
"message": "Rate limit created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"timeframe": [
"The timeframe field must be a valid enum value."
],
"block_time": [
"The block duration field must be a valid enum value."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"message": "Rate limit rule limit reached (25 rules per zone)",
"http_status": 422
}
Update Rate Limit
Updates an existing rate limit rule. All fields are optional - only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
rule
required
|
integer |
The rate limit rule ID. Example:
12345 |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
optional
|
string |
The rule name (max 255 characters). Example:
"Updated Rate Limit" |
|
description
optional
|
string |
The rule description (max 1000 characters). Example:
"Updated description for the rule" |
|
request_count
optional
|
integer |
Number of requests allowed within the timeframe. Must be between 1 and 1,000,000. Example:
200 |
|
timeframe
optional
|
integer |
Time window for counting requests. Must be exactly 1 (per second) or 10 (per 10 seconds). Example:
10 |
|
block_time
optional
|
integer |
Duration to block clients who exceed the limit, in seconds. Must be one of: 30, 60, 300, 900, 1800, 3600. Example:
300 |
|
value
optional
|
string |
URL path or pattern to match against. Max 2048 characters. Example:
"/api/v2/*" |
|
operator
optional
|
string |
Match operator for comparing against the value. Must be one of: begins-with, ends-with, contains, contains-word, str-match, eq, ge, gt, le, lt, within, regex, str-eq, detect-sqli, detect-xss. Example:
"regex" |
|
transformations
optional
|
string[] |
Transformations to apply to variable values before matching. Each must be one of: cmdline, compress-whitespace, css-decode, hex-encode, html-entity-decode, js-decode, length, lowercase, md5, normalize-path, normalise-path, normalize-path-win, normalise-path-win, remove-comments, remove-nulls, remove-whitespace, replace-comments, sha1, url-decode, url-decode-uni, utf8-to-unicode. Example:
["lowercase"] |
|
variables
optional
|
string[] |
Request variables to inspect when matching. Each must be one of: request-uri, request-uri-raw, args, args-combined-size, args-get, args-get-names, args-post, args-post-names, files-names, geo, remote-addr, query-string, request-basename, request-body, request-cookies-names, request-cookies, request-filename, request-headers-names, request-headers, request-line, request-method, request-protocol, response-body, response-headers, response-status. Example:
["request-uri","query-string"] |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/rate-limits/12345" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"Updated Rate Limit","description":"Updated description for the rule","request_count":200,"timeframe":10,"block_time":300,"value":"/api/v2/*","operator":"regex","transformations":["lowercase"],"variables":["request-uri","query-string"]}'
$response = $client->sites->waf->updateRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
'12345',
[
'name' => 'Updated Rate Limit',
'description' => 'Updated description for the rule',
'request_count' => 200,
'timeframe' => 10,
'block_time' => 300,
'value' => '/api/v2/*',
'operator' => 'regex',
'transformations' => ['lowercase'],
'variables' => ['request-uri', 'query-string'],
]
);
const rateLimit = await client.sites.waf.updateRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
'12345',
{
name: 'Updated Rate Limit',
description: 'Updated description for the rule',
request_count: 200,
timeframe: 10,
block_time: 300,
value: '/api/v2/*',
operator: 'regex',
transformations: ['lowercase'],
variables: ['request-uri', 'query-string'],
}
);
Response
{
"data": {
"id": 12345,
"name": "Updated Rate Limit",
"description": "Updated description for the rule",
"shield_zone_id": 67890,
"configuration": {
"request_count": 200,
"timeframe": 10,
"block_time": 300,
"value": "/api/v2/*",
"action": "rate-limit",
"operator": "regex",
"variables": [
"request-uri",
"query-string"
],
"transformations": [
"lowercase"
]
}
},
"message": "Rate limit updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Rate limit not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"operator": [
"The match operator field must be a valid enum value."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Rate Limit
Permanently deletes a rate limit rule. This action cannot be undone.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
rule
required
|
integer |
The rate limit rule ID. Example:
12345 |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/rate-limits/12345" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->deleteRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
'12345'
);
const response = await client.sites.waf.deleteRateLimit(
'01jfgxk4nqrst5vwx9yz0abcde',
'12345'
);
Response
{
"data": {},
"message": "Rate limit deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Rate limit not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
WAF: Referrers
Control which sites can link to your content using referrer-based rules.
- Blocked Referrers: Block hotlinking from specific domains
- Allowed Referrers: Restrict access to requests from approved domains only
Supports wildcards: *.example.com matches all subdomains.
List Allowed Referrers
Retrieves all allowed referrer hostnames for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/allowed-referrers" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->listAllowedReferrers('01jfgxk4nqrst5vwx9yz0abcde');
const referrers = await client.sites.waf.listAllowedReferrers('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": [
{
"hostname": "example.com"
},
{
"hostname": "*.example.net"
}
],
"message": "Allowed referrers retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Add Allowed Referrer
Adds a hostname to the allowed referrers list. Wildcards are supported (e.g., *.example.com).
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
hostname
required
|
string |
The hostname to allow. Example:
"example.com" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/allowed-referrers" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"hostname":"example.com"}'
$response = $client->sites->waf->addAllowedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'hostname' => 'example.com',
]
);
const response = await client.sites.waf.addAllowedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
{
hostname: 'example.com',
}
);
Response
{
"data": {
"hostname": "example.com"
},
"message": "Allowed referrer added successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"hostname": [
"The hostname field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Remove Allowed Referrer
Removes a hostname from the allowed referrers list.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
hostname
required
|
string |
The hostname to remove. Example:
"example.com" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/allowed-referrers/example.com" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->removeAllowedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
'example.com'
);
const response = await client.sites.waf.removeAllowedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
'example.com'
);
Response
{
"data": {
"hostname": "example.com"
},
"message": "Allowed referrer removed successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Allowed referrer not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
List Blocked Referrers
Retrieves all blocked referrer hostnames for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/blocked-referrers" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->listBlockedReferrers('01jfgxk4nqrst5vwx9yz0abcde');
const referrers = await client.sites.waf.listBlockedReferrers('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": [
{
"hostname": "spam.example.com"
},
{
"hostname": "*.example.net"
}
],
"message": "Blocked referrers retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Add Blocked Referrer
Adds a hostname to the blocked referrers list. Wildcards are supported (e.g., *.example.com).
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
hostname
required
|
string |
The hostname to block. Example:
"spam.example.com" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/blocked-referrers" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"hostname":"spam.example.com"}'
$response = $client->sites->waf->addBlockedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'hostname' => 'spam.example.com',
]
);
const response = await client.sites.waf.addBlockedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
{
hostname: 'spam.example.com',
}
);
Response
{
"data": {
"hostname": "spam.example.com"
},
"message": "Blocked referrer added successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"hostname": [
"The hostname field is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Remove Blocked Referrer
Removes a hostname from the blocked referrers list.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
hostname
required
|
string |
The hostname to remove. Example:
"spam.example.com" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/waf/blocked-referrers/spam.example.com" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->sites->waf->removeBlockedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
'spam.example.com'
);
const response = await client.sites.waf.removeBlockedReferrer(
'01jfgxk4nqrst5vwx9yz0abcde',
'spam.example.com'
);
Response
{
"data": {
"hostname": "spam.example.com"
},
"message": "Blocked referrer removed successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Blocked referrer not found",
"http_status": 404
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
WAF: Settings
Manage WAF core configuration including execution mode, profiles, rule groups, and payload limits.
Get WAF Settings
Retrieves the current WAF configuration for a site.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/sites/architecto/waf/settings" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->sites.waf.settings
->get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.waf.settings
.get('architecto', '01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"enabled": true,
"learning_mode": false,
"profile_id": 1,
"execution_mode": 1,
"disabled_rules": [],
"log_only_rules": [],
"request_header_logging": false,
"request_body_limit_action": 0,
"response_body_limit_action": 0,
"realtime_threat_intelligence": true
},
"message": "WAF settings retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Update WAF Settings
Updates WAF configuration for a site. All fields are optional — only include fields you want to change. Omitted fields retain their current values.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site. Example:
"architecto" |
|
vectorSite
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
enabled
optional
|
boolean |
Enable or disable WAF. Example:
true |
|
learning_mode
optional
|
boolean |
Enable learning mode (log without blocking). |
|
profile_id
optional
|
integer |
WAF profile ID. Example:
1 |
|
execution_mode
optional
|
integer |
WAF execution mode (0=Log, 1=Block). Example:
1 |
|
disabled_rules
optional
|
string[] |
Array of individual disabled rule IDs. Example:
["rule-1"] |
|
log_only_rules
optional
|
string[] |
Array of rules set to log-only mode. Example:
["rule-2"] |
|
request_header_logging
optional
|
boolean |
Log request headers. |
|
request_body_limit_action
optional
|
integer |
Request body limit action (0=ProcessPartial, 1=Reject, 2=Ignore). Example:
0 |
|
response_body_limit_action
optional
|
integer |
Response body limit action (0=ProcessPartial, 1=Reject, 2=Ignore). Example:
0 |
|
realtime_threat_intelligence
optional
|
boolean |
Enable realtime threat intelligence feeds. Example:
true |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/sites/architecto/waf/settings" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"enabled":true,"learning_mode":false,"profile_id":1,"execution_mode":1,"disabled_rules":["rule-1"],"log_only_rules":["rule-2"],"request_header_logging":false,"request_body_limit_action":0,"response_body_limit_action":0,"realtime_threat_intelligence":true}'
$response = $vectorPro
->sites.waf.settings
->put('architecto', '01jfgxk4nqrst5vwx9yz0abcde', [
'enabled' => true,
'learning_mode' => false,
'profile_id' => 1,
'execution_mode' => 1,
'disabled_rules' => ['rule-1'],
'log_only_rules' => ['rule-2'],
'request_header_logging' => false,
'request_body_limit_action' => 0,
'response_body_limit_action' => 0,
'realtime_threat_intelligence' => true,
]);
const response = await vectorPro
.sites.waf.settings
.put('architecto', '01jfgxk4nqrst5vwx9yz0abcde', {
enabled: true,
learning_mode: false,
profile_id: 1,
execution_mode: 1,
disabled_rules: ['rule-1'],
log_only_rules: ['rule-2'],
request_header_logging: false,
request_body_limit_action: 0,
response_body_limit_action: 0,
realtime_threat_intelligence: true,
});
Response
{
"data": {
"enabled": true,
"learning_mode": false,
"execution_mode": 1
},
"message": "WAF settings updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"execution_mode": [
"The execution mode must be 0 (Log) or 1 (Block)."
]
},
"message": "Validation failed",
"http_status": 422
}
WordPress
Manage WordPress configuration for your site’s development container.
Regenerate wp-config.php
Regenerates the wp-config.php file for the site’s development container with current database credentials, WP_HOME/WP_SITEURL, and HMAC secret.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X POST \ "https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/wp/reconfig" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $vectorPro
->sites.wp.reconfig
->post('01jfgxk4nqrst5vwx9yz0abcde');
const response = await vectorPro
.sites.wp.reconfig
.post('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": null,
"status": "active",
"status_label": "Active",
"dev_php_version": "8.3",
"tags": [],
"dev_domain": "wispy-dust.vectorpages.com",
"environments": [],
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "WordPress configuration regenerated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"status": [
"Site must be active to regenerate wp-config. Current state: 'pending'."
]
},
"message": "Site must be active to regenerate wp-config. Current state: 'pending'.",
"http_status": 422
}
Environments
Manage deployment environments for sites. Each site can have multiple environments with their own domains, PHP versions, and secrets. Environment names use a slug format (lowercase letters, numbers, and hyphens).
Environments are created with a pending status and transition to active once
container provisioning completes. Each environment gets a unique subdomain under
your registered domain.
Environment Status Lifecycle
pending- Environment creation initiated, provisioning in progressactive- Environment is fully operationalsuspended- Environment is pausedterminating- Environment deletion in progressterminated- Environment has been fully removed
Production Environment
Each site can have at most one production environment (is_production: true).
The production environment receives CDN integration via Bunny.net.
List Environments
Retrieves a paginated list of environments. Filter by site using the optional
site parameter, or list all environments for the authenticated account.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
site
optional
|
string |
Filter by site ID or subdomain. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments?site=01jfgxk4nqrst5vwx9yz0abcde&per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$environments = $client->environments->list([
'site' => '01jfgxk4nqrst5vwx9yz0abcde',
'per_page' => 25,
'page' => 1,
]);
const environments = await client.environments.listAll({
site: '01jfgxk4nqrst5vwx9yz0abcde',
per_page: 25,
page: 1,
});
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.3",
"tags": [
"live",
"primary"
],
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"dns_target": "site-abc123.b-cdn.net",
"custom_domain_certificate": {
"status": "issued",
"dns_validation_records": null
},
"subdomain": "wispy-dust",
"database_host": "cluster.abc123.us-east-1.rds.amazonaws.com",
"database_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Environments retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
Get Environment
Retrieves details of a specific environment.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$environment = $client->environments->get('01jfgxk4nqrst5vwx9yz0abcdg');
const environment = await client.environments.get('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.3",
"tags": [
"live",
"primary"
],
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"dns_target": "site-abc123.b-cdn.net",
"custom_domain_certificate": {
"status": "issued",
"dns_validation_records": null
},
"subdomain": "wispy-dust",
"database_host": "cluster.abc123.us-east-1.rds.amazonaws.com",
"database_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Update Environment
Updates an existing environment. Only the fields provided will be updated.
When custom_domain changes, a domain change operation is initiated asynchronously
(SSL certificate provisioning, search-replace, env sync, redeployment). The response
includes a pending_domain_change object for polling status. Returns 202 for domain
changes and 200 for metadata-only updates.
DNS Requirements
After setting a custom domain, the domain owner must create two types of DNS records:
- CNAME for traffic routing — Point the custom domain to the
dns_targetvalue (e.g.,example.com CNAME cdn-hostname.b-cdn.net). - CNAME(s) for SSL certificate validation — Create the DNS records listed in
custom_domain_certificate.dns_validation_records. These are required by AWS ACM to issue the SSL certificate. Until these records are created, the certificate status will remainwaiting_validation.
Poll the environment (GET) to check custom_domain_certificate.status for progress.
Possible values: pending, requesting, waiting_validation, issued, failed, timed_out.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
custom_domain
optional
|
string |
A custom vanity domain for this environment. Must be a valid domain name. When changed, triggers infrastructure updates (CDN, DNS, SSL). Example:
"example.com" |
|
tags
optional
|
string[] |
Array of tags for categorizing the environment. Each tag must be slug format (lowercase letters, numbers, hyphens), max 100 characters, and unique. Pass Example:
["live","updated"] |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"custom_domain":"example.com","tags":["live","updated"]}'
$environment = $client->environments->update(
'01jfgxk4nqrst5vwx9yz0abcdg',
[
'custom_domain' => 'example.com',
'tags' => ['live', 'updated'],
]
);
const environment = await client.environments.update(
'01jfgxk4nqrst5vwx9yz0abcdg',
{
custom_domain: 'example.com',
tags: ['live', 'updated'],
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.4",
"tags": [
"live",
"updated"
],
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"dns_target": "site-abc123.b-cdn.net",
"custom_domain_certificate": {
"status": "issued",
"dns_validation_records": null
},
"subdomain": "wispy-dust",
"database_host": "cluster.abc123.us-east-1.rds.amazonaws.com",
"database_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment updated successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.3",
"tags": [
"live",
"primary"
],
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"dns_target": "site-abc123.b-cdn.net",
"custom_domain_certificate": {
"status": "pending",
"dns_validation_records": [
{
"name": "_abc123.example.com",
"type": "CNAME",
"value": "_def456.acm-validations.aws"
}
]
},
"subdomain": "wispy-dust",
"database_host": "cluster.abc123.us-east-1.rds.amazonaws.com",
"database_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"pending_domain_change": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"status": "pending",
"status_label": "Pending",
"old_domain": "old.example.com",
"new_domain": "example.com"
},
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment update initiated, domain change in progress",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
{
"data": {},
"errors": {
"environment": [
"Environment must be in active state to change domain."
]
},
"message": "Environment must be in active state to change domain.",
"http_status": 422
}
{
"data": {},
"errors": {
"domain_change": [
"A domain change is already in progress for this environment."
]
},
"message": "A domain change is already in progress for this environment.",
"http_status": 422
}
Delete Environment
Initiates deletion of an environment. This terminates all associated
containers, deployments, and CDN resources. The environment status
transitions to terminating and eventually terminated.
This operation is irreversible. All environment data will be permanently removed.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->environments->delete('01jfgxk4nqrst5vwx9yz0abcdg');
const response = await client.environments.delete('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "terminating",
"status_label": "Terminating",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.3",
"tags": [],
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"dns_target": "site-abc123.b-cdn.net",
"custom_domain_certificate": {
"status": "issued",
"dns_validation_records": null
},
"subdomain": "wispy-dust",
"database_host": "cluster.abc123.us-east-1.rds.amazonaws.com",
"database_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment deletion initiated",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Create Environment
Creates a new environment for a site. The environment is created with a
pending status and will transition to active once provisioning completes.
Each environment gets a unique auto-generated subdomain and uses the site’s configured domain.
Important: Only one environment per site can be marked as production
(is_production: true). The production environment receives CDN integration.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
site
required
|
string |
The site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
name
required
|
string |
A unique name for this environment (slug format: lowercase letters, numbers, hyphens; consecutive hyphens Example:
"production" |
|
custom_domain
required
|
string |
The custom domain for this environment. Must be a valid fully qualified domain name. Max 253 chars. Example:
"example.com" |
|
is_production
optional
|
boolean |
Whether this is the production environment. Only one per site. Default: false. Example:
true |
|
php_version
required
|
string |
The PHP version for this environment. Options: 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5. Example:
"8.3" |
|
tags
optional
|
string[] |
Optional array of tags for categorizing the environment. Each tag must be slug format (lowercase letters, numbers, hyphens), max 100 characters, and unique. Example:
["live","primary"] |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/sites/01jfgxk4nqrst5vwx9yz0abcde/environments" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"production","custom_domain":"example.com","is_production":true,"php_version":"8.3","tags":["live","primary"]}'
$environment = $client->environments->create(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'name' => 'production',
'custom_domain' => 'example.com',
'is_production' => true,
'php_version' => '8.3',
'tags' => ['live', 'primary'],
]
);
const environment = await client.environments.create(
'01jfgxk4nqrst5vwx9yz0abcde',
{
name: 'production',
custom_domain: 'example.com',
is_production: true,
php_version: '8.3',
tags: ['live', 'primary'],
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "pending",
"status_label": "Pending",
"provisioning_step": "pending",
"failure_reason": null,
"php_version": "8.3",
"tags": [
"live",
"primary"
],
"platform_domain": "wispy-dust--prod.vectorpages.com",
"custom_domain": "example.com",
"dns_target": "site-abc123.b-cdn.net",
"custom_domain_certificate": {
"status": "pending",
"dns_validation_records": null
},
"subdomain": "wispy-dust",
"database_host": "cluster.abc123.us-east-1.rds.amazonaws.com",
"database_name": "db_01jfgxk4nqrst5vwx9yz0abcde",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment creation initiated",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Site not found",
"http_status": 404
}
{
"data": {},
"errors": {
"name": [
"Environment name must be lowercase letters, numbers, and hyphens only."
]
},
"message": "Validation failed",
"http_status": 422
}
{
"data": {},
"errors": {
"name": [
"Environment name must not contain consecutive hyphens (--)."
]
},
"message": "Validation failed",
"http_status": 422
}
Databases
Manage database credentials for production environments. Each environment has its own isolated database with credentials that can be rotated for security.
Create Database Promote
Promote the dev database to this environment. Exports the dev database, then imports it into the environment’s database.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
drop_tables
optional
|
boolean |
Whether to drop existing tables before importing. Defaults to true. Example:
true |
|
disable_foreign_keys
optional
|
boolean |
Whether to disable foreign key checks during import. Defaults to true. Example:
true |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcde/db/promote" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"drop_tables":true,"disable_foreign_keys":true}'
$response = $vectorPro
->environments.db.promote
->post('01jfgxk4nqrst5vwx9yz0abcde', [
'drop_tables' => true,
'disable_foreign_keys' => true,
]);
const response = await vectorPro
.environments.db.promote
.post('01jfgxk4nqrst5vwx9yz0abcde', {
drop_tables: true,
disable_foreign_keys: true,
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_db_export_id": null,
"status": "pending",
"status_label": "Pending",
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": null,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": null,
"completed_at": null
},
"message": "Database promote initiated",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
{
"data": {},
"errors": {
"environment": [
"Environment must be in active state to promote database."
]
},
"message": "Environment must be in active state to promote database.",
"http_status": 422
}
{
"data": {},
"errors": {
"promote": [
"A database promote is already in progress for this environment."
]
},
"message": "A database promote is already in progress for this environment.",
"http_status": 422
}
Get Promote Status
Get the current status of a database promote operation.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
promote
required
|
string |
The promote ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdf" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcde/db/promotes/01jfgxk4nqrst5vwx9yz0abcdf" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->environments.db.promotes
->get('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdf');
const response = await vectorPro
.environments.db.promotes
.get('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdf');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_db_export_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "completed",
"status_label": "Completed",
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": 12500,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00"
},
"message": "Database promote retrieved successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_db_export_id": null,
"status": "exporting",
"status_label": "Exporting",
"options": {
"drop_tables": true,
"disable_foreign_keys": true,
"search_replace": null
},
"duration_ms": null,
"error_message": null,
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": null
},
"message": "Database promote retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Promote not found",
"http_status": 404
}
Reset Password
Rotates the database password for a production environment via Ymir. The old password is immediately invalidated.
The new password is returned ONLY in this response. Store it securely—it cannot be retrieved again.
After rotating the password, you must redeploy the environment for your application to pick up the new credentials.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X POST \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/db/reset-password" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $vectorPro
->environments.db.resetPassword
->post('01jfgxk4nqrst5vwx9yz0abcdg');
const response = await vectorPro
.environments.db.resetPassword
.post('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.3",
"tags": [],
"platform_domain": "wispy-dust.vectorpages.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"database_user": "user_abc123_production",
"database_password": "aBcD1234!@#$EfGh5678",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Database password reset successfully. Store the new password securely - it will not be shown again. Remember to redeploy your environment.",
"http_status": 200
}
{
"data": {},
"message": "Environment does not have a database user configured. Deploy the environment first.",
"http_status": 400
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
{
"data": {},
"message": "Failed to rotate database password",
"http_status": 500
}
Deployments
Manage code deployments to environments. Each deployment represents a release of your WordPress site to a specific environment (staging or production).
Deployments are created with a pending status and progress through deploying
to either deployed (success) or failed. Each deployment records the actor
who initiated it and timing information.
Deployment Status Lifecycle
pending- Deployment created, waiting to startdeploying- Deployment in progressdeployed- Deployment completed successfullyfailed- Deployment failed (check stdout/stderr for details)
Get Deployment
Retrieves details of a specific deployment including output logs and actor information.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
deployment
required
|
string |
The deployment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/deployments/01jfgxk4nqrst5vwx9yz0abcdh" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$deployment = $client->environments->deployments->get('01jfgxk4nqrst5vwx9yz0abcdh');
const deployment = await client.environments.deployments.get('01jfgxk4nqrst5vwx9yz0abcdh');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "deployed",
"status_label": "Deployed",
"stdout": "Building project...\nUploading assets...\nDeployment complete.",
"stderr": null,
"actor": "[email protected]",
"environment": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"php_version": "8.3",
"tags": [
"wordpress"
],
"fqdn": "example.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Deployment retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Deployment not found",
"http_status": 404
}
List Deployments
Retrieves a paginated list of all deployments for a specific environment, ordered by most recent first.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/deployments?per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$deployments = $client->environments->deployments->list(
'01jfgxk4nqrst5vwx9yz0abcdg',
[
'per_page' => 25,
'page' => 1,
]
);
const deployments = await client.environments.deployments.list(
'01jfgxk4nqrst5vwx9yz0abcdg',
{
per_page: 25,
page: 1,
}
);
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "deployed",
"status_label": "Deployed",
"stdout": "Deployment output...",
"stderr": null,
"actor": "[email protected]",
"environment": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"php_version": "8.3",
"tags": [
"wordpress"
],
"fqdn": "example.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Deployments retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Create Deployment
Triggers a new deployment for the environment. The deployment starts with
pending status and progresses through deploying to either deployed
or failed.
The authenticated user is recorded as the deployment actor.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
include_uploads
optional
|
boolean |
Whether to include wp-content/uploads in the deployment. Defaults to false. |
|
include_database
optional
|
boolean |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/deployments" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"include_uploads":false,"include_database":false}'
$deployment = $client->environments->deployments->create(
'01jfgxk4nqrst5vwx9yz0abcdg',
[
'include_uploads' => false,
'include_database' => false,
]
);
const deployment = await client.environments.deployments.create(
'01jfgxk4nqrst5vwx9yz0abcdg',
{
include_uploads: false,
include_database: false,
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "pending",
"status_label": "Pending",
"stdout": null,
"stderr": null,
"actor": "[email protected]",
"environment": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"php_version": "8.3",
"tags": [
"wordpress"
],
"fqdn": "example.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Deployment initiated",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Rollback Deployment
Triggers a rollback for the environment. By default, rolls back to the last successful deployment. Optionally, you can specify a target_deployment_id to rollback to a specific previous deployment.
The rollback creates a new deployment record with pending status that progresses
through running to either completed or failed.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
target_deployment_id
optional
|
string |
Optional deployment ID to rollback to. Must be a previous successful deployment. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/rollback" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"target_deployment_id":"01jfgxk4nqrst5vwx9yz0abcdh"}'
$deployment = $client->environments->deployments->rollback(
'01jfgxk4nqrst5vwx9yz0abcdg',
[
'target_deployment_id' => '01jfgxk4nqrst5vwx9yz0abcdh',
]
);
const deployment = await client.environments.deployments.rollback(
'01jfgxk4nqrst5vwx9yz0abcdg',
{
target_deployment_id: '01jfgxk4nqrst5vwx9yz0abcdh',
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdi",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "pending",
"status_label": "Pending",
"stdout": null,
"stderr": null,
"actor": "[email protected]",
"environment": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"name": "production",
"is_production": true
},
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Rollback initiated",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
{
"data": {},
"errors": {
"target_deployment_id": [
"The specified deployment does not exist for this environment or has no Ymir deployment ID."
]
},
"message": "Validation failed",
"http_status": 422
}
Domains
Check the status of domain change operations for an environment. Domain changes are initiated via the environment update endpoint.
Domain Change Status Lifecycle
pending- Domain change created, waiting to startsearch_replacing- Running search-replace on the databasesyncing_env- Syncing environment variables with new domainredeploying- Redeploying the environmentcompleted- Domain change finished successfullyfailed- Domain change failed (seeerror_messagefor details)
Get Domain Change Status
Get the current status of a domain change operation.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
domainChange
required
|
string |
The domain change ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcde/domain-changes/01jfgxk4nqrst5vwx9yz0abcdh" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->environments.domainChanges
->get('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdh');
const response = await vectorPro
.environments.domainChanges
.get('01jfgxk4nqrst5vwx9yz0abcde', '01jfgxk4nqrst5vwx9yz0abcdh');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_environment_id": "01jfgxk4nqrst5vwx9yz0abcde",
"status": "completed",
"status_label": "Completed",
"old_domain": "wispy-dust.vectorpages.com",
"new_domain": "wispy-dust.vectorpages.com",
"old_custom_domain": "example.org",
"new_custom_domain": "example.com",
"error_message": null,
"duration_ms": 12450,
"created_at": "2025-01-15T12:00:00+00:00",
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00"
},
"message": "Domain change retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Domain change not found",
"http_status": 404
}
Secrets
Manage environment-level secrets and environment variables for a specific environment. These are injected during site deployment and are scoped to a single environment.
Items with is_secret=true (the default) are stored in AWS Secrets Manager and their values
are never returned in API responses. Items with is_secret=false are stored as Lambda
environment variables and their values ARE returned in API responses.
Certain keys are reserved for system use and cannot be used.
List Secrets
Retrieves a paginated list of all secrets and environment variables for a specific environment.
Values are only included for environment variables (is_secret=false).
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
10 |
|
page
optional
|
integer |
Page number for pagination. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/secrets?per_page=10&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$secrets = $client->environments->secrets->list('01jfgxk4nqrst5vwx9yz0abcdg');
const secrets = await client.environments.secrets.list('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
{
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"key": "APP_ENV",
"is_secret": false,
"value": "production",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Environment secrets retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Create Secret
Creates a new secret or environment variable for a specific environment. It will be available to this environment during deployment.
Set is_secret to false to create a plain environment variable instead of a secret.
Environment variables are stored as Lambda env vars (cheaper) and their values are
returned in API responses. Secrets are stored in AWS Secrets Manager and their values
are never returned.
The following keys are reserved and cannot be used: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT, AUTOMATIC_UPDATER_DISABLED, DISABLE_WP_CRON, DISALLOW_FILE_EDIT, DISALLOW_FILE_MODS, DOMAIN_CURRENT_SITE, WP_HOME, WP_SITEURL, YMIR_ASSETS_PATH, YMIR_ASSETS_URL, YMIR_CACHE_PREFIX, YMIR_CACHE_TABLE, YMIR_CDN_IMAGE_PROCESSING_ENABLED, YMIR_DISTRIBUTION_ID, YMIR_DOMAIN_NAMES, YMIR_ENVIRONMENT, YMIR_MAX_EXECUTION_TIME, YMIR_PRIMARY_DOMAIN_NAME, YMIR_PROJECT_TYPE, YMIR_PUBLIC_STORE, YMIR_REDIS_ENDPOINT, YMIR_SECRETS_PATH, YMIR_UPLOAD_URL, _HANDLER, AWS_ACCESS_KEY_ID, AWS_EXECUTION_ENV, AWS_LAMBDA_FUNCTION_MEMORY_SIZE, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_VERSION, AWS_LAMBDA_LOG_GROUP_NAME, AWS_LAMBDA_LOG_STREAM_NAME, AWS_LAMBDA_RUNTIME_API, AWS_REGION, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, LAMBDA_RUNTIME_DIR, LAMBDA_TASK_ROOT, TZ
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
key
required
|
string |
The secret key name. Must start with a letter and contain only uppercase letters, numbers, and underscores. Example:
"STRIPE_SECRET_KEY" |
|
value
required
|
string |
The secret value. Example:
"sk_live_xxxx" |
|
is_secret
optional
|
boolean |
Whether this is a secret (stored in AWS Secrets Manager) or a plain environment variable. Default: true. Example:
true |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/secrets" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"key":"STRIPE_SECRET_KEY","value":"sk_live_xxxx","is_secret":true}'
$secret = $client->environments->secrets->create(
'01jfgxk4nqrst5vwx9yz0abcdg',
[
'key' => 'STRIPE_SECRET_KEY',
'value' => 'sk_live_xxxx',
'is_secret' => true,
]
);
const secret = await client.environments.secrets.create(
'01jfgxk4nqrst5vwx9yz0abcdg',
{
key: 'STRIPE_SECRET_KEY',
value: 'sk_live_xxxx',
is_secret: true,
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment secret created successfully",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
{
"data": {},
"errors": {
"key": [
"The secret key is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Get Secret
Retrieves details of a specific environment secret or variable.
The value is only included for environment variables (is_secret=false).
URL Parameters
| Name | Type | Description |
|---|---|---|
|
secret
required
|
string |
The secret ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/secrets/01jfgxk4nqrst5vwx9yz0abcde" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$secret = $client->environments->secrets->get('01jfgxk4nqrst5vwx9yz0abcde');
const secret = await client.environments.secrets.get('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment secret retrieved successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdf",
"key": "APP_ENV",
"is_secret": false,
"value": "production",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment secret retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment secret not found",
"http_status": 404
}
Update Secret
Updates an existing environment secret or variable. You can update the key, value, is_secret flag, or any combination.
The following keys are reserved and cannot be used: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT, AUTOMATIC_UPDATER_DISABLED, DISABLE_WP_CRON, DISALLOW_FILE_EDIT, DISALLOW_FILE_MODS, DOMAIN_CURRENT_SITE, WP_HOME, WP_SITEURL, YMIR_ASSETS_PATH, YMIR_ASSETS_URL, YMIR_CACHE_PREFIX, YMIR_CACHE_TABLE, YMIR_CDN_IMAGE_PROCESSING_ENABLED, YMIR_DISTRIBUTION_ID, YMIR_DOMAIN_NAMES, YMIR_ENVIRONMENT, YMIR_MAX_EXECUTION_TIME, YMIR_PRIMARY_DOMAIN_NAME, YMIR_PROJECT_TYPE, YMIR_PUBLIC_STORE, YMIR_REDIS_ENDPOINT, YMIR_SECRETS_PATH, YMIR_UPLOAD_URL, _HANDLER, AWS_ACCESS_KEY_ID, AWS_EXECUTION_ENV, AWS_LAMBDA_FUNCTION_MEMORY_SIZE, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_VERSION, AWS_LAMBDA_LOG_GROUP_NAME, AWS_LAMBDA_LOG_STREAM_NAME, AWS_LAMBDA_RUNTIME_API, AWS_REGION, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, LAMBDA_RUNTIME_DIR, LAMBDA_TASK_ROOT, TZ
URL Parameters
| Name | Type | Description |
|---|---|---|
|
secret
required
|
string |
The secret ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
key
optional
|
string |
The new secret key name. Must start with a letter and contain only uppercase letters, numbers, and underscores. Example:
"STRIPE_API_KEY" |
|
value
optional
|
string |
The new secret value. Example:
"sk_live_yyyy" |
|
is_secret
optional
|
boolean |
Whether this is a secret or a plain environment variable. Example:
true |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/secrets/01jfgxk4nqrst5vwx9yz0abcde" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"key":"STRIPE_API_KEY","value":"sk_live_yyyy","is_secret":true}'
$secret = $client->environments->secrets->update(
'01jfgxk4nqrst5vwx9yz0abcde',
[
'key' => 'STRIPE_API_KEY',
'value' => 'sk_live_yyyy',
'is_secret' => true,
]
);
const secret = await client.environments.secrets.update(
'01jfgxk4nqrst5vwx9yz0abcde',
{
key: 'STRIPE_API_KEY',
value: 'sk_live_yyyy',
is_secret: true,
}
);
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_API_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment secret updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment secret not found",
"http_status": 404
}
{
"data": {},
"errors": {
"key": [
"The secret key must start with a letter and contain only uppercase letters, numbers, and underscores."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Secret
Deletes an environment secret.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
secret
required
|
string |
The secret ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/secrets/01jfgxk4nqrst5vwx9yz0abcde" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->environments->secrets->delete('01jfgxk4nqrst5vwx9yz0abcde');
const response = await client.environments.secrets.delete('01jfgxk4nqrst5vwx9yz0abcde');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcde",
"key": "STRIPE_SECRET_KEY",
"is_secret": true,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Environment secret deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment secret not found",
"http_status": 404
}
SSL
Manage SSL provisioning for Vector environments.
SSL is automatically provisioned when environments are deployed. These endpoints provide visibility into SSL status and manual intervention capabilities when provisioning gets stuck.
Environment Status
The main status field tracks the environment lifecycle:
pending- Environment created, awaiting first deployprovisioning- Resources being provisioned (including SSL)active- Environment fully operationalfailed- Provisioning failed
Provisioning Step
The provisioning_step field tracks detailed progress during provisioning:
null- Not startedrequesting_cert- Requesting AWS ACM certificatewaiting_cert- Waiting for certificate validationdeploying- Deploying to Ymirconfiguring_dns- Configuring DNS recordsready- Platform SSL complete (terminal for staging)waiting_custom_dns- Waiting for custom domain DNS (production only)provisioning_cdn_ssl- Requesting Let’s Encrypt certificatecomplete- Fully complete (terminal for production with custom domain)
Get Status
Get the current SSL provisioning status for an environment.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/ssl" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$sslStatus = $client->sites->ssl->getStatus('01jfgxk4nqrst5vwx9yz0abcdg');
const sslStatus = await client.sites.ssl.getStatus('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "active",
"status_label": "Active",
"provisioning_step": "complete",
"failure_reason": null,
"php_version": "8.3",
"tags": [],
"platform_domain": "wispy-dust.vectorpages.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSL status retrieved",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Nudge
Manually nudge SSL provisioning for an environment. Use this when SSL provisioning appears to be stuck or to retry after a failure.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
env
required
|
string |
The environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
retry
optional
|
boolean |
Whether to retry from a failed state. Default: false. Example:
true |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/environments/01jfgxk4nqrst5vwx9yz0abcdg/ssl/nudge" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"retry":true}'
$response = $client->sites->ssl->nudge('01jfgxk4nqrst5vwx9yz0abcdg');
const response = await client.sites.ssl.nudge('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "provisioning",
"status_label": "Provisioning",
"provisioning_step": "deploying",
"failure_reason": null,
"php_version": "8.3",
"tags": [],
"platform_domain": "wispy-dust.vectorpages.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSL provisioning advanced from waiting_cert to deploying",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"vector_site_id": "01jfgxk4nqrst5vwx9yz0abcde",
"your_customer_id": "cust_12345",
"name": "production",
"is_production": true,
"status": "provisioning",
"status_label": "Provisioning",
"provisioning_step": "waiting_custom_dns",
"failure_reason": null,
"php_version": "8.3",
"tags": [],
"platform_domain": "wispy-dust.vectorpages.com",
"custom_domain": "example.com",
"subdomain": "wispy-dust",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "SSL provisioning is waiting and cannot advance yet. Current step: waiting_custom_dns",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Environment not found",
"http_status": 404
}
Authentication
Get authenticated user details
Returns the current user, active API token, and current account.
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/auth/whoami" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->api.v1.auth.whoami
->get();
const response = await vectorPro
.api.v1.auth.whoami
.get();
Response
{
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "[email protected]"
},
"token": {
"name": "vector-cli",
"abilities": [
"*"
],
"expires_at": null,
"last_used_at": "2026-03-14T12:00:00.000000Z"
},
"account": {
"id": 1,
"name": "Acme Inc"
}
},
"message": "Success",
"http_status": 200
}
{
"message": "Unauthenticated."
}
Backups
List Backups
Retrieves a paginated list of backups, optionally filtered by type, site, or environment.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
type
optional
|
string |
Filter by archivable type (site, environment). Example:
"site" |
|
site_id
optional
|
string |
Filter by site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
environment_id
optional
|
string |
Filter by environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/backups?type=site&site_id=01jfgxk4nqrst5vwx9yz0abcde&environment_id=01jfgxk4nqrst5vwx9yz0abcde&per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->backups
->get([
'type' => 'site',
'site_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'environment_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'per_page' => 25,
'page' => 1,
]);
const response = await vectorPro
.backups
.get({
type: 'site',
site_id: '01jfgxk4nqrst5vwx9yz0abcde',
environment_id: '01jfgxk4nqrst5vwx9yz0abcde',
per_page: 25,
page: 1,
});
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"archivable_type": "vector_site",
"archivable_id": "01jfgxk4nqrst5vwx9yz0abcde",
"type": "manual",
"type_label": "Manual",
"scope": "full",
"scope_label": "Full",
"status": "completed",
"status_label": "Completed",
"description": "Pre-deployment backup",
"file_snapshot_id": "abc123def456",
"database_snapshot_id": "ghi789jkl012",
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Backups retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Get Backup
Retrieves details of a specific backup.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
backup
required
|
string |
The backup ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/backups/01jfgxk4nqrst5vwx9yz0abcdg" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->backups
->get('01jfgxk4nqrst5vwx9yz0abcdg');
const response = await vectorPro
.backups
.get('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"archivable_type": "vector_site",
"archivable_id": "01jfgxk4nqrst5vwx9yz0abcde",
"type": "manual",
"type_label": "Manual",
"scope": "full",
"scope_label": "Full",
"status": "completed",
"status_label": "Completed",
"description": "Pre-deployment backup",
"file_snapshot_id": "abc123def456",
"database_snapshot_id": "ghi789jkl012",
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Backup retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Backup not found",
"http_status": 404
}
Create Backup
Creates a new backup for the specified site or environment. The backup is created with a
pending status and an async job is dispatched to orchestrate the restic backup via an
ECS task.
Body Parameters
| Name | Type | Description |
|---|---|---|
|
site_id
optional
|
string |
The site ID (required if environment_id not provided). Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
environment_id
optional
|
string |
The environment ID (required if site_id not provided). Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
type
required
|
string |
The backup type (manual, scheduled). Example:
"manual" |
|
scope
optional
|
string |
The backup scope (full, database, files). Default: full. Example:
"full" |
|
description
optional
|
string |
Optional description for the backup. Max 500 characters. Example:
"Pre-deployment backup" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/backups" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"site_id":"01jfgxk4nqrst5vwx9yz0abcde","environment_id":"01jfgxk4nqrst5vwx9yz0abcde","type":"manual","scope":"full","description":"Pre-deployment backup"}'
$response = $vectorPro
->backups
->post([
'site_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'environment_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'type' => 'manual',
'scope' => 'full',
'description' => 'Pre-deployment backup',
]);
const response = await vectorPro
.backups
.post({
site_id: '01jfgxk4nqrst5vwx9yz0abcde',
environment_id: '01jfgxk4nqrst5vwx9yz0abcde',
type: 'manual',
scope: 'full',
description: 'Pre-deployment backup',
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdg",
"archivable_type": "vector_site",
"archivable_id": "01jfgxk4nqrst5vwx9yz0abcde",
"type": "manual",
"type_label": "Manual",
"scope": "full",
"scope_label": "Full",
"status": "pending",
"status_label": "Pending",
"description": "Pre-deployment backup",
"file_snapshot_id": null,
"database_snapshot_id": null,
"started_at": null,
"completed_at": null,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Backup initiated successfully",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"site_id": [
"Either a site ID or environment ID is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Backup Downloads
Manage backup download requests. When a download is requested, an async job archives the backup snapshots and uploads the archive to S3. Once complete, a presigned download URL is available for a limited time.
Download Status Lifecycle
pending- Download record created, waiting for ECS task to startprocessing- ECS task is archiving the backup snapshotscompleted- Archive uploaded to S3, presigned URL availablefailed- Download failed (see error_message for details)
Get Backup Download
Retrieves the status of a backup download. If the download is complete and not expired, includes a presigned download URL.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
backup
required
|
string |
The backup ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
|
download
required
|
string |
The download ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/backups/01jfgxk4nqrst5vwx9yz0abcdg/downloads/01jfgxk4nqrst5vwx9yz0abcdh" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->backups.downloads
->get('01jfgxk4nqrst5vwx9yz0abcdg', '01jfgxk4nqrst5vwx9yz0abcdh');
const response = await vectorPro
.backups.downloads
.get('01jfgxk4nqrst5vwx9yz0abcdg', '01jfgxk4nqrst5vwx9yz0abcdh');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_backup_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "completed",
"status_label": "Completed",
"s3_key": "backups/downloads/01jfgxk4nqrst5vwx9yz0abcdh.tar.gz",
"size_bytes": 52428800,
"duration_ms": 12500,
"error_message": null,
"download_url": "https://s3.amazonaws.com/bucket/backups/downloads/01jfgxk4nqrst5vwx9yz0abcdh.tar.gz?presigned=...",
"download_expires_at": "2025-01-15T12:00:00+00:00",
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Backup download retrieved successfully",
"http_status": 200
}
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_backup_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "processing",
"status_label": "Processing",
"s3_key": null,
"size_bytes": null,
"duration_ms": null,
"error_message": null,
"download_url": null,
"download_expires_at": null,
"started_at": null,
"completed_at": null,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Backup download retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Backup download not found",
"http_status": 404
}
Create Backup Download
Creates a new download request for the specified backup. The download is created with a
pending status and an async job is dispatched to archive the backup snapshots.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
backup
required
|
string |
The backup ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdg" |
Response Codes
Request
curl -X POST \ "https://api.builtfast.com/api/v1/vector/backups/01jfgxk4nqrst5vwx9yz0abcdg/downloads" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$response = $vectorPro
->backups.downloads
->post('01jfgxk4nqrst5vwx9yz0abcdg');
const response = await vectorPro
.backups.downloads
.post('01jfgxk4nqrst5vwx9yz0abcdg');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"vector_backup_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"status": "pending",
"status_label": "Pending",
"s3_key": null,
"size_bytes": null,
"duration_ms": null,
"error_message": null,
"download_url": null,
"download_expires_at": null,
"started_at": null,
"completed_at": null,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Backup download initiated",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Backup not found",
"http_status": 404
}
Events
View event logs for Vector Pro resources. Events are logged automatically when actions occur (site creation, deployments, etc.) and are retained for 90 days.
Event logs provide an audit trail of all activity in your account.
Actor Tracking
Each event includes an actor object when the action was triggered via the API:
ip- The IP address of the requesttoken_name- The name of the API token used
The actor field is omitted for events triggered by system processes (scheduled tasks,
queue workers processing internal jobs, etc.) where no user context exists.
Event Naming Convention
Events follow a consistent dot-notation pattern:
- Simple actions:
{entity}.{action}(e.g.,site.created,site.updated) - Lifecycle operations:
{entity}.{operation}.{phase}(e.g.,site.provisioning.started)
Available Event Types
Site Events
| Event | Description |
|---|---|
site.created |
Site record has been created |
site.updated |
Site settings have been modified |
site.cloned |
Site has been cloned from another site |
site.provisioning.started |
Container provisioning has started |
site.provisioning.completed |
Site is fully provisioned and running |
site.provisioning.failed |
Site provisioning failed |
site.suspension.started |
Site suspension has started |
site.suspension.completed |
Site has been suspended |
site.unsuspension.started |
Site unsuspension has started |
site.unsuspension.completed |
Site has been unsuspended |
site.termination.started |
Site termination has started |
site.termination.completed |
Site has been terminated |
site.sftp.password.reset |
SFTP password has been reset |
site.database.password.reset |
Database password has been reset |
site.sshkey.added |
SSH key has been added to site |
site.sshkey.removed |
SSH key has been removed from site |
site.database.import.started |
Database import has started |
site.database.import.completed |
Database import completed successfully |
site.database.import.failed |
Database import failed |
site.database.export.started |
Database export has started |
site.database.export.completed |
Database export completed successfully |
site.database.export.failed |
Database export failed |
SSH Key Events
| Event | Description |
|---|---|
sshkey.created |
SSH key has been created |
sshkey.deleted |
SSH key has been deleted |
Environment Events
| Event | Description |
|---|---|
environment.created |
Production environment has been created |
environment.updated |
Environment settings have been modified |
environment.provisioning.started |
Environment provisioning has started |
environment.provisioning.completed |
Environment is fully provisioned |
environment.provisioning.failed |
Environment provisioning failed |
environment.suspension.started |
Environment suspension has started |
environment.suspension.completed |
Environment has been suspended |
environment.unsuspension.started |
Environment unsuspension has started |
environment.unsuspension.completed |
Environment has been unsuspended |
environment.termination.started |
Environment termination has started |
environment.termination.completed |
Environment has been terminated |
environment.database.password.reset |
Database password has been reset |
Deployment Events
| Event | Description |
|---|---|
deployment.started |
Deployment to production has started |
deployment.completed |
Deployment completed successfully |
deployment.failed |
Deployment failed |
deployment.rollback.started |
Deployment rollback has started |
deployment.rollback.completed |
Deployment rollback completed |
deployment.rollback.failed |
Deployment rollback failed |
CDN Events
| Event | Description |
|---|---|
cdn.setup.started |
CDN configuration has started |
cdn.setup.completed |
CDN setup completed successfully |
cdn.setup.failed |
CDN setup failed |
DNS Events
| Event | Description |
|---|---|
dns.record.created |
DNS record has been created |
dns.record.deleted |
DNS record has been deleted |
WAF Events
| Event | Description |
|---|---|
waf.ratelimit.created |
Rate limit rule has been created |
waf.ratelimit.updated |
Rate limit rule has been updated |
waf.ratelimit.deleted |
Rate limit rule has been deleted |
waf.blockedip.created |
IP block has been created |
waf.blockedip.deleted |
IP block has been removed |
waf.blockedreferrer.created |
Referrer block has been created |
waf.blockedreferrer.deleted |
Referrer block has been removed |
waf.allowedreferrer.created |
Allowed referrer has been added |
waf.allowedreferrer.deleted |
Allowed referrer has been removed |
Secret Events
| Event | Description |
|---|---|
secret.created |
Secret has been created |
secret.updated |
Secret has been updated |
secret.deleted |
Secret has been deleted |
Domain Events
| Event | Description |
|---|---|
domain.created |
Domain has been registered |
domain.deleted |
Domain has been deleted |
API Key Events
| Event | Description |
|---|---|
apikey.created |
API key has been created |
apikey.deleted |
API key has been deleted |
Webhook Events
| Event | Description |
|---|---|
webhook.created |
Webhook endpoint has been registered |
webhook.updated |
Webhook configuration has been modified |
webhook.deleted |
Webhook endpoint has been removed |
Cache Events
| Event | Description |
|---|---|
cache.purged |
Cache has been purged |
List Events
Retrieves a paginated list of event logs for the authenticated account. Logs are returned in reverse chronological order (newest first).
Event logs are automatically pruned after 90 days.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
from
optional
|
string |
Filter events that occurred on or after this timestamp (ISO 8601). Example:
"2025-01-01T00:00:00+00:00" |
|
to
optional
|
string |
Filter events that occurred on or before this timestamp (ISO 8601). Example:
"2025-01-31T23:59:59+00:00" |
|
event
optional
|
string |
Filter by event type(s). Accepts a single event or comma-separated list. Example:
"site.provisioning.completed,deployment.completed" |
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/events?from=2025-01-01T00%3A00%3A00%2B00%3A00&to=2025-01-31T23%3A59%3A59%2B00%3A00&event=site.provisioning.completed%2Cdeployment.completed&per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$events = $client->events->list([
'from' => '2025-01-01T00:00:00+00:00',
'to' => '2025-01-31T23:59:59+00:00',
'event' => 'site.provisioning.completed,deployment.completed',
'per_page' => 25,
'page' => 1,
]);
const events = await client.events.list({
from: '2025-01-01T00:00:00+00:00',
to: '2025-01-31T23:59:59+00:00',
event: 'site.provisioning.completed,deployment.completed',
per_page: 25,
page: 1,
});
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdl",
"event": "site.provisioning.completed",
"model_type": "VectorSite",
"model_id": "01jfgxk4nqrst5vwx9yz0abcde",
"context": null,
"actor": {
"id": 1,
"ip": "192.0.2.1",
"token_id": 1,
"token_name": "Production API Key"
},
"occurred_at": "2025-01-15T12:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Event logs retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Restores
List Restores
Retrieves a paginated list of restores, optionally filtered by type, site, environment, or backup.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
type
optional
|
string |
Filter by archivable type (site, environment). Example:
"site" |
|
site_id
optional
|
string |
Filter by site ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
environment_id
optional
|
string |
Filter by environment ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
backup_id
optional
|
string |
Filter by backup ID. Example:
"01jfgxk4nqrst5vwx9yz0abcde" |
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/restores?type=site&site_id=01jfgxk4nqrst5vwx9yz0abcde&environment_id=01jfgxk4nqrst5vwx9yz0abcde&backup_id=01jfgxk4nqrst5vwx9yz0abcde&per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->restores
->get([
'type' => 'site',
'site_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'environment_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'backup_id' => '01jfgxk4nqrst5vwx9yz0abcde',
'per_page' => 25,
'page' => 1,
]);
const response = await vectorPro
.restores
.get({
type: 'site',
site_id: '01jfgxk4nqrst5vwx9yz0abcde',
environment_id: '01jfgxk4nqrst5vwx9yz0abcde',
backup_id: '01jfgxk4nqrst5vwx9yz0abcde',
per_page: 25,
page: 1,
});
Response
{
"data": [
{
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"archivable_type": "vector_site",
"archivable_id": "01jfgxk4nqrst5vwx9yz0abcde",
"scope": "full",
"scope_label": "Full",
"trigger": "manual",
"trigger_label": "Manual",
"status": "completed",
"status_label": "Completed",
"vector_backup_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"search_replace": null,
"drop_tables": false,
"disable_foreign_keys": false,
"error_message": null,
"duration_ms": 45200,
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
}
],
"links": {},
"meta": {},
"message": "Restores retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Get Restore
Retrieves details of a specific restore.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
restore
required
|
string |
The restore ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdh" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/restores/01jfgxk4nqrst5vwx9yz0abcdh" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $vectorPro
->restores
->get('01jfgxk4nqrst5vwx9yz0abcdh');
const response = await vectorPro
.restores
.get('01jfgxk4nqrst5vwx9yz0abcdh');
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"archivable_type": "vector_site",
"archivable_id": "01jfgxk4nqrst5vwx9yz0abcde",
"scope": "full",
"scope_label": "Full",
"trigger": "manual",
"trigger_label": "Manual",
"status": "completed",
"status_label": "Completed",
"vector_backup_id": "01jfgxk4nqrst5vwx9yz0abcdg",
"search_replace": [
{
"from": "example.org",
"to": "example.com"
}
],
"drop_tables": false,
"disable_foreign_keys": false,
"error_message": null,
"duration_ms": 45200,
"started_at": "2025-01-15T12:00:00+00:00",
"completed_at": "2025-01-15T12:00:00+00:00",
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Restore retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Restore not found",
"http_status": 404
}
Create Restore
Creates a new restore from a previously completed backup. The archivable (site or
environment) is inferred from the backup. The restore is created with a pending
status and an async job is dispatched to orchestrate the restic restore via an ECS task.
Body Parameters
| Name | Type | Description |
|---|---|---|
|
backup_id
required
|
string |
The ID of a completed backup to restore from. Must be a valid ULID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
|
scope
optional
|
string |
The restore scope (full, database, files). Default: full. Example:
"full" |
|
search_replace
optional
|
string[] |
Optional search and replace pairs. Example:
[{"from":"example.org","to":"example.com"}] |
|
drop_tables
optional
|
boolean |
Whether to drop existing tables before restore. Default: false. |
|
disable_foreign_keys
optional
|
boolean |
Whether to disable foreign key checks during restore. Default: false. |
|
search_replace[].from
required
|
string |
Must not be greater than 255 characters. Example:
"n" |
|
search_replace[].to
required
|
string |
Must not be greater than 255 characters. Example:
"g" |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/restores" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"backup_id":"01jfgxk4nqrst5vwx9yz0abcdi","scope":"full","search_replace":[{"from":"example.org","to":"example.com"}],"drop_tables":false,"disable_foreign_keys":false}'
$response = $vectorPro
->restores
->post([
'backup_id' => '01jfgxk4nqrst5vwx9yz0abcdi',
'scope' => 'full',
'search_replace' => [[
'from' => 'example.org',
'to' => 'example.com',
]],
'drop_tables' => false,
'disable_foreign_keys' => false,
]);
const response = await vectorPro
.restores
.post({
backup_id: '01jfgxk4nqrst5vwx9yz0abcdi',
scope: 'full',
search_replace: [{
from: 'example.org',
to: 'example.com',
}],
drop_tables: false,
disable_foreign_keys: false,
});
Response
{
"data": {
"id": "01jfgxk4nqrst5vwx9yz0abcdh",
"archivable_type": "vector_site",
"archivable_id": "01jfgxk4nqrst5vwx9yz0abcde",
"scope": "full",
"scope_label": "Full",
"trigger": "manual",
"trigger_label": "Manual",
"status": "pending",
"status_label": "Pending",
"vector_backup_id": "01jfgxk4nqrst5vwx9yz0abcdi",
"search_replace": [
{
"from": "example.org",
"to": "example.com"
}
],
"drop_tables": false,
"disable_foreign_keys": false,
"error_message": null,
"duration_ms": null,
"started_at": null,
"completed_at": null,
"created_at": "2025-01-15T12:00:00+00:00",
"updated_at": "2025-01-15T12:00:00+00:00"
},
"message": "Restore initiated successfully",
"http_status": 202
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"backup_id": [
"A backup ID is required."
]
},
"message": "Validation failed",
"http_status": 422
}
Webhooks
Manage webhooks that receive site event notifications. Webhooks are called when events occur on your sites (deployments, status changes, etc.).
Supports both HTTP webhooks and Slack webhooks for notifications.
Webhook Signature Verification
HTTP webhook payloads include an X-Vector-Signature header for verifying
authenticity. The header format is:
X-Vector-Signature: t=1234567890,v1=abc123...
To verify a webhook:
- Parse the timestamp (
t) and signature (v1) from the header - Construct the signed message:
{timestamp}.{raw_request_body} - Compute HMAC-SHA256 using your webhook secret as the key
- Compare with the provided signature using constant-time comparison
- Validate timestamp is within tolerance (recommended: 5 minutes)
Example verification (PHP):
$header = $request->header('X-Vector-Signature');
preg_match('/t=(\d+),v1=([a-f0-9]+)/', $header, $matches);
$timestamp = $matches[1];
$signature = $matches[2];
$message = $timestamp . '.' . $request->getContent();
$expected = hash_hmac('sha256', $message, $webhookSecret);
if (!hash_equals($expected, $signature)) {
throw new Exception('Invalid signature');
}
if (abs(time() - (int)$timestamp) > 300) {
throw new Exception('Timestamp too old');
}
List Webhooks
Retrieves a paginated list of all webhooks for the authenticated account. Webhook secrets are never included in list responses.
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/webhooks?per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$webhooks = $client->webhooks->list();
const webhooks = await client.webhooks.list({
per_page: 25,
page: 1,
});
Response
{
"data": [
{
"id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"account_id": 1,
"type": "http",
"type_label": "Http",
"url": "https://example.com/webhook",
"events": [
"site.created",
"deployment.completed"
],
"enabled": true,
"created_at": "2025-05-27T09:50:21+00:00",
"updated_at": "2025-05-27T09:50:21+00:00"
}
],
"links": {},
"meta": {},
"message": "Webhooks retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
Get Webhook
Retrieves details of a specific webhook. The secret is never included in this response - use the rotate-secret endpoint if you need a new secret.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
webhook
required
|
string |
The webhook ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/webhooks/01jfgxk4nqrst5vwx9yz0abcdi" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$webhook = $client->webhooks->get('01jfgxk4nqrst5vwx9yz0abcdi');
const webhook = await client.webhooks.get('01jfgxk4nqrst5vwx9yz0abcdi');
Response
{
"data": {
"id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"account_id": 1,
"type": "http",
"type_label": "Http",
"url": "https://example.com/webhook",
"events": [
"site.created",
"deployment.completed"
],
"enabled": true,
"created_at": "2025-05-27T09:50:21+00:00",
"updated_at": "2025-05-27T09:50:21+00:00"
},
"message": "Webhook retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Webhook not found",
"http_status": 404
}
Create Webhook
Creates a new webhook for the current account.
For HTTP webhooks, the secret is returned ONLY in this response. Store it securely—it cannot be retrieved again (only rotated via the rotate-secret endpoint).
Slack webhooks do not require secrets as they use URL-based authentication.
Body Parameters
| Name | Type | Description |
|---|---|---|
|
type
optional
|
string |
The webhook type. Options: Example:
"http" |
|
url
required
|
string |
The webhook URL. For HTTP: must use HTTPS. For Slack: must be a Slack webhook URL. Example:
"https://example.com/webhook" |
|
events
required
|
string[] |
Array of events to subscribe to. See available events below. Example:
["site.created","deployment.completed"] |
|
enabled
optional
|
boolean |
Whether the webhook is enabled. Default: true. Example:
true |
Response Codes
Request
curl -X POST \
"https://api.builtfast.com/api/v1/vector/webhooks" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"type":"http","url":"https://example.com/webhook","events":["site.created","deployment.completed"],"enabled":true}'
$webhook = $client->webhooks->create([
'type' => 'http',
'url' => 'https://example.com/webhook',
'events' => ['site.created', 'deployment.completed'],
'enabled' => true,
]);
const webhook = await client.webhooks.create({
type: 'http',
url: 'https://example.com/webhook',
events: ['site.created', 'deployment.completed'],
enabled: true,
});
Response
{
"data": {
"id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"account_id": 1,
"type": "http",
"type_label": "Http",
"url": "https://example.com/webhook",
"events": [
"site.created",
"deployment.completed"
],
"secret": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234abcd",
"enabled": true,
"created_at": "2025-05-27T09:50:21+00:00",
"updated_at": "2025-05-27T09:50:21+00:00"
},
"message": "Webhook created successfully. Store the secret securely - it will not be shown again.",
"http_status": 201
}
{
"data": {
"id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"account_id": 1,
"type": "slack",
"type_label": "Slack",
"url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
"events": [
"deployment.completed",
"deployment.failed"
],
"enabled": true,
"created_at": "2025-05-27T09:50:21+00:00",
"updated_at": "2025-05-27T09:50:21+00:00"
},
"message": "Slack webhook created successfully.",
"http_status": 201
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"errors": {
"events": [
"At least one event must be specified."
]
},
"message": "Validation failed",
"http_status": 422
}
Update Webhook
Updates an existing webhook configuration. The secret cannot be updated through this endpoint - use the rotate-secret endpoint instead.
The webhook type cannot be changed after creation.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
webhook
required
|
string |
The webhook ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Body Parameters
| Name | Type | Description |
|---|---|---|
|
url
optional
|
string |
The webhook URL. Must use HTTPS for HTTP webhooks. Example:
"https://example.com/new-webhook" |
|
events
optional
|
string[] |
Array of events to subscribe to. Example:
["site.created","site.updated"] |
|
enabled
optional
|
boolean |
Whether the webhook is enabled. |
Response Codes
Request
curl -X PUT \
"https://api.builtfast.com/api/v1/vector/webhooks/01jfgxk4nqrst5vwx9yz0abcdi" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"url":"https://example.com/new-webhook","events":["site.created","site.updated"],"enabled":false}'
$webhook = $client->webhooks->update(
'01jfgxk4nqrst5vwx9yz0abcdi',
[
'url' => 'https://example.com/new-webhook',
'events' => ['site.created', 'site.updated'],
'enabled' => false,
]
);
const webhook = await client.webhooks.update(
'01jfgxk4nqrst5vwx9yz0abcdi',
{
url: 'https://example.com/new-webhook',
events: ['site.created', 'site.updated'],
enabled: false,
}
);
Response
{
"data": {
"id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"account_id": 1,
"type": "http",
"type_label": "Http",
"url": "https://example.com/new-webhook",
"events": [
"site.created",
"site.updated"
],
"enabled": false,
"created_at": "2025-05-27T09:50:21+00:00",
"updated_at": "2025-05-27T10:30:45+00:00"
},
"message": "Webhook updated successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Webhook not found",
"http_status": 404
}
{
"data": {},
"errors": {
"events": [
"At least one event must be specified."
]
},
"message": "Validation failed",
"http_status": 422
}
Delete Webhook
Deletes a webhook. All associated delivery logs will also be deleted. This operation is irreversible.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
webhook
required
|
string |
The webhook ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Response Codes
Request
curl -X DELETE \ "https://api.builtfast.com/api/v1/vector/webhooks/01jfgxk4nqrst5vwx9yz0abcdi" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->webhooks->delete('01jfgxk4nqrst5vwx9yz0abcdi');
const response = await client.webhooks.delete('01jfgxk4nqrst5vwx9yz0abcdi');
Response
{
"data": {
"id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"account_id": 1,
"type": "http",
"type_label": "Http",
"url": "https://example.com/webhook",
"events": [
"site.created"
],
"enabled": true,
"created_at": "2025-05-27T09:50:21+00:00",
"updated_at": "2025-05-27T09:50:21+00:00"
},
"message": "Webhook deleted successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Webhook not found",
"http_status": 404
}
List Logs
Retrieves a paginated list of delivery logs for a specific webhook. Logs are returned in reverse chronological order (newest first).
Each log entry includes the event type, request payload, response details, and latency information. Logs are automatically pruned after 90 days.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
webhook
required
|
string |
The webhook ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Query Parameters
| Name | Type | Description |
|---|---|---|
|
per_page
optional
|
integer |
Number of items per page (max 100). Default: 15. Example:
25 |
|
page
optional
|
integer |
Page number for pagination. Default: 1. Example:
1 |
Response Codes
Request
curl -X GET \ "https://api.builtfast.com/api/v1/vector/webhooks/01jfgxk4nqrst5vwx9yz0abcdi/logs?per_page=25&page=1" \ -H "Authorization: Bearer $API_KEY" \ -H "Accept: application/json"
$response = $client->webhooks->listLogs(
'01jfgxk4nqrst5vwx9yz0abcdi',
[
'per_page' => 25,
'page' => 1,
]
);
const response = await client.webhooks.listLogs(
'01jfgxk4nqrst5vwx9yz0abcdi',
{
per_page: 25,
page: 1,
}
);
Response
{
"data": [
{
"id": "01JFGXK4NQRST5VWX9YZ0ABCDJ",
"vector_webhook_delivery_id": "01JFGXK4NQRST5VWX9YZ0ABCDK",
"vector_webhook_id": "01JFGXK4NQRST5VWX9YZ0ABCDI",
"event": "vector.site.created",
"request_body": {
"event": "vector.site.created",
"data": {}
},
"attempt": 1,
"response_status": 200,
"response_body": "{\"success\": true}",
"response_headers": {
"content-type": "application/json"
},
"latency_ms": 150,
"created_at": "2025-05-27T09:50:21+00:00"
}
],
"links": {},
"meta": {},
"message": "Webhook logs retrieved successfully",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Webhook not found",
"http_status": 404
}
Rotate Secret
Generates a new secret for the webhook. The old secret is immediately invalidated and any pending deliveries will use the new secret.
The new secret is returned ONLY in this response. Store it securely—it cannot be retrieved again.
This endpoint is only available for HTTP webhooks. Slack webhooks do not use secrets.
URL Parameters
| Name | Type | Description |
|---|---|---|
|
webhook
required
|
string |
The webhook ID. Example:
"01jfgxk4nqrst5vwx9yz0abcdi" |
Response Codes
Request
curl -X POST \ "https://api.builtfast.com/api/v1/vector/webhooks/01jfgxk4nqrst5vwx9yz0abcdi/rotate-secret" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json"
$webhook = $client->webhooks->rotateSecret('01jfgxk4nqrst5vwx9yz0abcdi');
const webhook = await client.webhooks.rotateSecret('01jfgxk4nqrst5vwx9yz0abcdi');
Response
{
"data": {
"secret": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234abcd"
},
"message": "Webhook secret rotated successfully. Store the new secret securely - it will not be shown again.",
"http_status": 200
}
{
"data": {},
"message": "Unauthenticated",
"http_status": 401
}
{
"data": {},
"message": "Unauthorized",
"http_status": 403
}
{
"data": {},
"message": "Webhook not found",
"http_status": 404
}