Vector Pro

Provision, deploy, and manage serverless WordPress sites on AWS Lambda infrastructure with enterprise-grade CDN, WAF, and DNS services.

Base URL https://api.builtfast.com/api/v1/vector
Private Beta Vector Pro is currently in private beta. Get in touch to request access.

Authentication

All requests require Bearer token authentication via the Authorization header.

Authorization: Bearer {YOUR_API_TOKEN}
Keep tokens secure. Never expose in client-side code.

Quick Start

1 Create a site POST/sites
2 Upload via SFTP ssh.myvectorsite.com
3 Deploy POST/deployments
View full walkthrough

Response Format

200 Single Resource
{
  "data": {
    "id": "01HQ7KXYZ...",
    "type": "production",
    "status": "active"
  },
  "message": "Success",
  "http_status": 200
}
200 Collection
{
  "data": [
    { "id": "01HQ7K..." },
    { "id": "01HQ7L..." }
  ],
  "links": { "next": "..." },
  "meta": { "total": 42 }
}
422 Validation Error
{
  "errors": {
    "type": ["Required"],
    "php_version": ["Invalid"]
  },
  "message": "Validation failed"
}

Status Codes

200Success
201Created
202Accepted (async)
400Bad request
401Unauthorized
404Not found
422Validation error
429Rate limited

Rate Limits

Default120/min
Logs60/hour
Deployments30/hour
Cache Purge60/hour
Site Mutations10/hour
Credentials10/hour
DB Operations10/hour
Headers: X-RateLimit-Remaining

Pagination

pagePage number (default: 1)
per_pageItems per page (max: 100)
Response includes links and meta objects

Async Operations

Site creation, environments, and deployments return 202 and process asynchronously.

Configure webhooks for notifications

SDKs & Tools

PHP
composer require built-fast/vector-pro-sdk
Node
npm install @built-fast/vector-pro-sdk
CLI
brew install built-fast/devtools/vector-cli
Copy for AI

Click the sparkle icon on any endpoint to copy its OpenAPI spec—ready to paste into your favorite LLM.

"Generate a PHP function to create a site" "Write error handling for this endpoint" "Create TypeScript types from this spec"
View all developer tools

Account

Manage your Vector Pro account settings including API keys, SSH keys, and global secrets.

GET /account

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
application/json
{
  "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
}
PATCH /account

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 YOUR_ID. Pass null to clear it.

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
application/json
{
  "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.

GET /api-keys

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
application/json
{
  "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
}
POST /api-keys

Create API Key

Creates a new API key for the authenticated user.

Warning

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 information
  • site:read - Read sites, environments, deployments, database operations
  • site:write - Manage sites, environments, deployments, database import/export
  • domain:read - Read domains
  • domain:write - Manage domains
  • log:read - Read site logs
  • cdn:read - Read CDN settings
  • cdn:write - Manage CDN settings and cache
  • webhook:read - Read webhooks
  • webhook:write - Manage webhooks
  • secret:read - Read API keys and global secrets
  • secret:write - Manage API keys and global secrets
  • sshkey:read - Read SSH keys
  • sshkey:write - Manage SSH keys
  • events: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
application/json
{
  "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-keys/{token}

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
application/json
{
  "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.

GET /global-secrets

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
application/json
{
  "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 /global-secrets/{secret}

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
application/json
{
  "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
}
POST /global-secrets

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
application/json
{
  "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
}
PUT /global-secrets/{secret}

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
application/json
{
  "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 /global-secrets/{secret}

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
application/json
{
  "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.

GET /ssh-keys

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
application/json
{
  "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-keys/{key}

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
application/json
{
  "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
}
POST /ssh-keys

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
application/json
{
  "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-keys/{key}

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
application/json
{
  "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.

GET /php-versions

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
application/json
{
  "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 progress
  • active - Site is fully operational and serving traffic
  • suspended - Site is paused to reduce costs (can be unsuspended)
  • terminating - Site deletion in progress
  • terminated - Site has been fully removed
GET /sites

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 your_customer_id or subdomain (partial, case-insensitive).

Example: "acme"
status
optional
string

Filter by site status. Must be one of: pending, activation_requested, active, suspension_requested, suspended, unsuspension_requested, termination_requested, terminated, canceled.

Example: "active"
sort
optional
string

Sort results by the given field. Must be one of: created_at, updated_at, status, your_customer_id, last_deployed_at. Default: created_at.

Example: "your_customer_id"
direction
optional
string

Sort direction. Must be asc or desc. Default: desc.

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
application/json
{
  "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 /sites/{site}

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
application/json
{
  "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
}
POST /sites

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 custom_domain_certificate and dns_target fields on the environment for details.

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 custom_domain_certificate and dns_target fields on the environment for details.

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 wp_admin block containing the generated password is only returned in this creation response.

wp_admin_user
optional
string

Optional WordPress admin username. Only used when wp_admin_email is provided. Defaults to “admin”. Max 60 characters.

Example: "myadmin"
wp_site_title
optional
string

Optional WordPress site title. Only used when wp_admin_email is provided. Defaults to “WordPress” in the container. Max 255 characters.

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
application/json
{
  "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
}
PUT /sites/{site}

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 null to clear tags.

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
application/json
{
  "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 /sites/{site}

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
application/json
{
  "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
}
POST /sites/{site}/clone

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
application/json
{
  "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
}
PUT /sites/{site}/suspend

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
application/json
{
  "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
}
PUT /sites/{site}/unsuspend

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
application/json
{
  "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.

POST /sites/{site}/purge-cache

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
application/json
{
  "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 /sites/{site}/cdn/caching

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
application/json
{
  "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
}
PUT /sites/{site}/cdn/caching

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
application/json
{
  "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
GET /sites/{site}/cdn/edge-rules

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
application/json
{
  "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 /sites/{site}/cdn/edge-rules/{rule}

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
application/json
{
  "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
}
POST /sites/{site}/cdn/edge-rules

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
application/json
{
  "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
}
PUT /sites/{site}/cdn/edge-rules/{rule}

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
application/json
{
  "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 /sites/{site}/cdn/edge-rules/{rule}

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
application/json
{
  "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 /sites/{site}/cdn/optimizer

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
application/json
{
  "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
}
PUT /sites/{site}/cdn/optimizer

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
application/json
{
  "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.

POST /sites/{site}/db/export

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
application/json
{
  "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 /sites/{site}/db/exports/{export}

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
application/json
{
  "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
}
POST /sites/{site}/db/reset-password

Reset Password

Generates a new database password for the site’s development container. The old password is immediately invalidated.

Warning

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
application/json
{
  "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.

GET /sites/{site}/deployments

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
application/json
{
  "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 /sites/{site}/imports/{import}

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
application/json
{
  "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
}
POST /sites/{site}/imports

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
application/json
{
  "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
}
POST /sites/{site}/imports/{import}/run

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
application/json
{
  "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 /sites/{site}/logs

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
application/json
{
  "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.

POST /sites/{site}/sftp/reset-password

Reset Password

Generates a new SFTP password for the site’s development container. The old password is immediately invalidated.

Warning

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
application/json
{
  "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.

GET /sites/{site}/ssh-keys

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
application/json
{
  "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
}
POST /sites/{site}/ssh-keys

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
application/json
{
  "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
}
DELETE /sites/{site}/ssh-keys/{key}

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
application/json
{
  "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.

GET /sites/{site}/waf/access-lists

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
application/json
{
  "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 /sites/{site}/waf/access-lists/{listId}

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
application/json
{
  "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
}
POST /sites/{site}/waf/access-lists

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
application/json
{
  "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
}
PATCH /sites/{site}/waf/access-lists/{listId}

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
application/json
{
  "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 /sites/{site}/waf/access-lists/{listId}

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
application/json
{
  "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
}
PATCH /sites/{site}/waf/access-lists/configurations/{configId}

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
application/json
{
  "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 /sites/{site}/waf/access-lists/enums

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
application/json
{
  "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
GET /sites/{site}/waf/blocked-ips

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
application/json
{
  "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
}
POST /sites/{site}/waf/blocked-ips

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
application/json
{
  "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
}
DELETE /sites/{site}/waf/blocked-ips/{ip}

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
application/json
{
  "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 /sites/{site}/waf/bot-detection

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
application/json
{
  "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
}
PUT /sites/{site}/waf/bot-detection

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
application/json
{
  "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 /sites/{site}/waf/ddos

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
application/json
{
  "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
}
PUT /sites/{site}/waf/ddos

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
application/json
{
  "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.

GET /sites/{site}/waf/profiles

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
application/json
{
  "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.

GET /sites/{site}/waf/rate-limits

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
application/json
{
  "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 /sites/{site}/waf/rate-limits/{rule}

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
application/json
{
  "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
}
POST /sites/{site}/waf/rate-limits

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
application/json
{
  "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
}
PUT /sites/{site}/waf/rate-limits/{rule}

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
application/json
{
  "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 /sites/{site}/waf/rate-limits/{rule}

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
application/json
{
  "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.

GET /sites/{site}/waf/allowed-referrers

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
application/json
{
  "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
}
POST /sites/{site}/waf/allowed-referrers

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
application/json
{
  "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
}
DELETE /sites/{site}/waf/allowed-referrers/{hostname}

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
application/json
{
  "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
}
GET /sites/{site}/waf/blocked-referrers

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
application/json
{
  "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
}
POST /sites/{site}/waf/blocked-referrers

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
application/json
{
  "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
}
DELETE /sites/{site}/waf/blocked-referrers/{hostname}

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
application/json
{
  "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 /sites/{site}/waf/settings

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
application/json
{
  "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
}
PUT /sites/{site}/waf/settings

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
application/json
{
  "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.

POST /sites/{site}/wp/reconfig

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
application/json
{
  "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 progress
  • active - Environment is fully operational
  • suspended - Environment is paused
  • terminating - Environment deletion in progress
  • terminated - 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.

GET /environments

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
application/json
{
  "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 /environments/{env}

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
application/json
{
  "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
}
PUT /environments/{env}

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:

  1. CNAME for traffic routing — Point the custom domain to the dns_target value (e.g., example.com CNAME cdn-hostname.b-cdn.net).
  2. 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 remain waiting_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 null to clear tags.

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
application/json
{
  "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 /environments/{env}

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
application/json
{
  "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
}
POST /sites/{site}/environments

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 -- are not allowed). Max 50 chars.

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
application/json
{
  "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.

POST /environments/{env}/db/promote

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
application/json
{
  "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 /environments/{env}/db/promotes/{promote}

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
application/json
{
  "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
}
POST /environments/{env}/db/reset-password

Reset Password

Rotates the database password for a production environment via Ymir. The old password is immediately invalidated.

Warning

The new password is returned ONLY in this response. Store it securely—it cannot be retrieved again.

Note

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
application/json
{
  "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 start
  • deploying - Deployment in progress
  • deployed - Deployment completed successfully
  • failed - Deployment failed (check stdout/stderr for details)
GET /deployments/{deployment}

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
application/json
{
  "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
}
GET /environments/{env}/deployments

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
application/json
{
  "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
}
POST /environments/{env}/deployments

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
application/json
{
  "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
}
POST /environments/{env}/rollback

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
application/json
{
  "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 start
  • search_replacing - Running search-replace on the database
  • syncing_env - Syncing environment variables with new domain
  • redeploying - Redeploying the environment
  • completed - Domain change finished successfully
  • failed - Domain change failed (see error_message for details)
GET /environments/{env}/domain-changes/{domainChange}

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
application/json
{
  "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.

GET /environments/{env}/secrets

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
application/json
{
  "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
}
POST /environments/{env}/secrets

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
application/json
{
  "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 /secrets/{secret}

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
application/json
{
  "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
}
PUT /secrets/{secret}

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
application/json
{
  "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 /secrets/{secret}

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
application/json
{
  "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 deploy
  • provisioning - Resources being provisioned (including SSL)
  • active - Environment fully operational
  • failed - Provisioning failed
Provisioning Step

The provisioning_step field tracks detailed progress during provisioning:

  • null - Not started
  • requesting_cert - Requesting AWS ACM certificate
  • waiting_cert - Waiting for certificate validation
  • deploying - Deploying to Ymir
  • configuring_dns - Configuring DNS records
  • ready - Platform SSL complete (terminal for staging)
  • waiting_custom_dns - Waiting for custom domain DNS (production only)
  • provisioning_cdn_ssl - Requesting Let’s Encrypt certificate
  • complete - Fully complete (terminal for production with custom domain)
GET /environments/{env}/ssl

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
application/json
{
  "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
}
POST /environments/{env}/ssl/nudge

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
application/json
{
  "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 /api/v1/auth/whoami

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
application/json
{
  "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

GET /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
application/json
{
  "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 /backups/{backup}

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
application/json
{
  "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
}
POST /backups

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
application/json
{
  "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 start
  • processing - ECS task is archiving the backup snapshots
  • completed - Archive uploaded to S3, presigned URL available
  • failed - Download failed (see error_message for details)
GET /backups/{backup}/downloads/{download}

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
application/json
{
  "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
}
POST /backups/{backup}/downloads

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
application/json
{
  "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 request
  • token_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
GET /events

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
application/json
{
  "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

GET /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
application/json
{
  "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 /restores/{restore}

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
application/json
{
  "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
}
POST /restores

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
application/json
{
  "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:

  1. Parse the timestamp (t) and signature (v1) from the header
  2. Construct the signed message: {timestamp}.{raw_request_body}
  3. Compute HMAC-SHA256 using your webhook secret as the key
  4. Compare with the provided signature using constant-time comparison
  5. 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');
}
GET /webhooks

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
application/json
{
  "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 /webhooks/{webhook}

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
application/json
{
  "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
}
POST /webhooks

Create Webhook

Creates a new webhook for the current account.

Warning

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: http, slack. Default: http.

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
application/json
{
  "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
}
PUT /webhooks/{webhook}

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
application/json
{
  "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 /webhooks/{webhook}

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
application/json
{
  "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
}
GET /webhooks/{webhook}/logs

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
application/json
{
  "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
}
POST /webhooks/{webhook}/rotate-secret

Rotate Secret

Generates a new secret for the webhook. The old secret is immediately invalidated and any pending deliveries will use the new secret.

Warning

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
application/json
{
  "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
}