ForgedBase API v1

Developer API Reference

Use the ForgedBase API to inspect account state, list infrastructure, read operational history, and trigger safe deployment automation while preserving the same ownership, permission, plan, and audit rules used by the dashboard.

API Playground

Base URL

https://forgedbase.com/api/v1

API auth

Bearer API key

Format

JSON request and response bodies

Rate limits

Plan-aware per API key

Tooling spec

Copy the OpenAPI URL into API clients

Ability scopes

Readable list below, discovery endpoint available

Start here

Authentication

Bearer-token endpoints require an API key created from the authenticated dashboard settings area. API key management endpoints use a normal verified web session and CSRF protection, because the full token is only returned during key creation.

API key setup

Create keys in Settings

Open Settings > API Keys in the authenticated dashboard. Choose a name, expiry, and abilities, then copy the generated token immediately. Replace YOUR_API_KEY in the bearer examples below with that token.

Open API key settings

ForgedBase API endpoint

The API endpoint is built from the configured ForgedBase application URL. Use this endpoint for provider, server, site, deployment, account, and usage automation.

Base URL API v1
https://forgedbase.com/api/v1

Authenticated request

Send the API key in the Authorization header as a bearer token. The profile endpoint is a safe first request to verify the key and workspace context.

Example request
use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/profile');

$data = $response->json();

Response format

Errors

API errors keep Laravel-compatible message and validation errors fields, plus a stable machine-readable error object for integrations.

Missing or invalid API key

401
Example response JSON
{
  "message": "Unauthenticated.",
  "error": {
    "code": "unauthenticated",
    "status": 401
  }
}

Forbidden ability, permission, or plan access

403
Example response JSON
{
  "message": "This API key is not allowed to perform that action.",
  "error": {
    "code": "forbidden",
    "status": 403
  }
}

Validation failed

422
Example response JSON
{
  "message": "The name field is required.",
  "errors": {
    "name": ["The name field is required."]
  },
  "error": {
    "code": "validation_failed",
    "status": 422
  }
}

Rate limit exceeded

429
Example response JSON
{
  "message": "Too Many Attempts.",
  "error": {
    "code": "rate_limited",
    "status": 429
  }
}

Account

Profile

Inspect the authenticated user and the API key used for the request.

GET /profile

Returns the current user, workspace owner context, and API key metadata.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/profile');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "user": {
      "id": 42,
      "name": "Riley Morgan",
      "email": "riley@example.com",
      "timezone": "Europe/Dublin"
    },
    "workspace": {
      "id": 42,
      "name": "Riley's workspace"
    },
    "api_key": {
      "id": 12,
      "name": "Deployment Bot",
      "token_prefix": "fbak_abcd1234efgh5"
    }
  }
}

Account

Account

Read workspace/account details. Requires account settings permission.

GET /account

Returns the selected workspace owner, display name, timezone, and current plan key.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/account');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 42,
    "name": "Client Launch Workspace",
    "owner_name": "Riley Morgan",
    "owner_email": "riley@example.com",
    "timezone": "Europe/Dublin",
    "plan": "pro"
  }
}

Billing

Plan

Read the current plan and API rate limit available to the workspace.

GET /plan

Returns plan labels, resource limits, and the API request limit.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/plan');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "key": "pro",
    "label": "Pro",
    "limits": {
      "servers": 2,
      "sites": null,
      "mail_profiles": null,
      "team_members": 2,
      "api_requests_per_minute": 300
    },
    "features": {
      "database_backups": true,
      "mail_rotation": true,
      "team_access": true
    }
  }
}

Billing

Usage

Inspect current resource usage against the plan.

GET /usage

Returns counts for plan-limited resources and API request limit context.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/usage');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "servers": { "used": 1, "limit": 2 },
    "sites": { "used": 4, "limit": null },
    "mail_profiles": { "used": 2, "limit": null },
    "team_members": { "used": 1, "limit": 2 },
    "api": { "requests_per_minute": 300 }
  }
}

Infrastructure

Servers

Create, inspect, update, and queue deletion for owned servers. Mutating requests use the same provisioning/deletion services as the dashboard.

GET /servers

Lists owned servers with safe operational fields.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers?per_page=25');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 7,
      "name": "Production App Server",
      "provider": "digitalocean",
      "hostname": "app-01.example.com",
      "public_ipv4": "203.0.113.10",
      "public_ipv6": null,
      "status": "ready",
      "type": "app",
      "ssh_port": 22,
      "last_provisioned_at": "2026-06-01T12:00:00.000000Z",
      "created_at": "2026-06-01T11:30:00.000000Z",
      "updated_at": "2026-06-06T09:20:00.000000Z"
    }
  ]
}
POST /servers

Creates a server record and queues provisioning. Provider, region, size, image, and SSH key IDs must belong to the authenticated workspace.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/servers', [
    'provider_connection_id' => 3,
    'provider_region_id' => 12,
    'provider_size_id' => 27,
    'provider_image_id' => 44,
    'provider_ssh_key_ids' => [
        '0' => 9,
    ],
    'name' => 'Production App Server',
    'hostname' => 'app-01',
    'server_type' => 'app',
    'stack' => [
        'install_nginx' => true,
        'install_php' => true,
        'php_version' => 8.3,
        'database' => 'mysql',
    ],
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 7,
    "name": "Production App Server",
    "hostname": "app-01",
    "status": "queued",
    "type": "app"
  }
}
GET /servers/{serverId}

Shows one owned, plan-manageable server.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 7,
    "name": "Production App Server",
    "provider": "digitalocean",
    "hostname": "app-01.example.com",
    "public_ipv4": "203.0.113.10",
    "status": "ready",
    "type": "app",
    "ssh_port": 22
  }
}
PATCH /servers/{serverId}

Updates editable server settings such as display name, SSH port, IP fields, timezone, or provider credential link.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->patch('https://forgedbase.com/api/v1/servers/7', [
    'name' => 'Production App Server',
    'ssh_port' => 2222,
    'timezone' => 'Europe/Dublin',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 7,
    "name": "Production App Server",
    "ssh_port": 2222,
    "status": "ready"
  }
}
PUT /servers/{serverId}

Replaces the editable server settings accepted by the update endpoint. Omitted infrastructure/runtime fields are not changed.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->put('https://forgedbase.com/api/v1/servers/7', [
    'name' => 'Production App Server',
    'ssh_port' => 22,
    'public_ipv4' => '203.0.113.10',
    'private_ipv4' => '10.0.0.10',
    'timezone' => 'Europe/Dublin',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 7,
    "name": "Production App Server",
    "ssh_port": 22,
    "status": "ready"
  }
}
DELETE /servers/{serverId}

Queues full server deletion through the same deletion job used by the dashboard. Locked servers require prior dashboard email verification.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/servers/7');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "message": "Server deletion queued.",
  "data": {
    "id": 7,
    "deletion_id": 88,
    "status": "deleting"
  }
}

Applications

Sites

Create, inspect, update runtime/source-control settings, and queue deletion for sites.

GET /sites

Lists owned sites. Internal runtime-only records remain hidden by existing scopes.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites?per_page=25');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 18,
      "server_id": 7,
      "domain": "example.com",
      "type": "laravel",
      "status": "ready",
      "ssl": { "enabled": true, "active": true },
      "visit_url": "https://example.com",
      "last_provisioned_at": "2026-06-02T15:00:00.000000Z",
      "failure_message": null,
      "created_at": "2026-06-02T14:40:00.000000Z",
      "updated_at": "2026-06-06T09:20:00.000000Z"
    }
  ]
}
POST /sites

Creates a site and queues provisioning on a ready app server.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites', [
    'server_id' => 7,
    'domain' => 'example.com',
    'application' => 'laravel',
    'source_control' => [
        'provider_connection_id' => 11,
        'repository' => 'acme/example',
        'branch' => 'main',
    ],
    'dns' => [
        'auto_configure' => true,
    ],
    'primary_domain' => [
        'wildcard_enabled' => false,
        'redirect_mode' => 'from_www',
    ],
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 18,
    "server_id": 7,
    "domain": "example.com",
    "type": "php",
    "status": "queued"
  }
}
GET /sites/{siteId}

Shows one owned, plan-manageable site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 18,
    "server_id": 7,
    "domain": "example.com",
    "type": "laravel",
    "status": "ready",
    "ssl": { "enabled": true, "active": true },
    "visit_url": "https://example.com"
  }
}
PATCH /sites/{siteId}

Updates editable site runtime and source-control settings once the current provisioning run is idle.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->patch('https://forgedbase.com/api/v1/sites/18', [
    'php_version' => 8.3,
    'source_control' => [
        'provider_connection_id' => 11,
        'repository' => 'acme/example',
        'branch' => 'main',
        'install_composer_dependencies' => true,
    ],
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 18,
    "server_id": 7,
    "domain": "example.com",
    "status": "ready"
  }
}
PUT /sites/{siteId}

Replaces the editable site settings accepted by the update endpoint. Domain changes use the Domains endpoints.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->put('https://forgedbase.com/api/v1/sites/18', [
    'php_version' => 8.3,
    'source_control' => [
        'provider_connection_id' => 11,
        'repository' => 'acme/example',
        'branch' => 'main',
    ],
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 18,
    "status": "ready"
  }
}
DELETE /sites/{siteId}

Queues site deletion through the dashboard deletion job.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/sites/18');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "message": "Site deletion queued.",
  "data": {
    "id": 18,
    "deletion_id": 91,
    "status": "deleting"
  }
}

Network

Site domains

Create, update, promote, enable, disable, and remove custom site domains. Domain operations queue the same remote work used by the dashboard.

GET /sites/{siteId}/domains

Lists domains for an owned, plan-manageable site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/domains');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 31,
      "site_id": 18,
      "domain": "www.example.com",
      "status": "active",
      "is_primary": false,
      "redirect_mode": "to_apex",
      "wildcard_enabled": false,
      "installed_at": "2026-06-02T15:10:00.000000Z"
    }
  ]
}
POST /sites/{siteId}/domains

Adds a custom domain and queues installation.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/domains', [
    'domain' => 'www.example.com',
    'wildcard_enabled' => false,
    'redirect_mode' => 'from_www',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "site_id": 18,
    "domain": "www.example.com",
    "status": "installing",
    "wildcard_enabled": false,
    "redirect_mode": "from_www"
  }
}
GET /sites/{siteId}/domains/{domainId}

Shows one domain belonging to the site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/domains/31');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "site_id": 18,
    "domain": "www.example.com",
    "status": "active",
    "redirect_mode": "to_apex"
  }
}
PATCH /sites/{siteId}/domains/{domainId}

Updates wildcard and redirect settings for a custom domain. Active domains queue config refresh.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->patch('https://forgedbase.com/api/v1/sites/18/domains/31', [
    'wildcard_enabled' => true,
    'redirect_mode' => 'none',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "status": "installing",
    "wildcard_enabled": true,
    "redirect_mode": "none"
  }
}
PUT /sites/{siteId}/domains/{domainId}

Replaces the editable domain settings accepted by the update endpoint.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->put('https://forgedbase.com/api/v1/sites/18/domains/31', [
    'wildcard_enabled' => false,
    'redirect_mode' => 'from_www',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "status": "installing"
  }
}
DELETE /sites/{siteId}/domains/{domainId}

Queues custom domain removal. Certificates covering the domain must be removed first.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/sites/18/domains/31');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "domain": "www.example.com",
    "status": "removing"
  }
}
POST /sites/{siteId}/domains/{domainId}/promote

Queues a custom domain promotion to primary.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/domains/31/promote');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "status": "installing"
  }
}
POST /sites/{siteId}/domains/{domainId}/disable

Queues a custom domain disable operation.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/domains/31/disable');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "status": "disabling"
  }
}
POST /sites/{siteId}/domains/{domainId}/enable

Queues a disabled custom domain to be enabled again.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/domains/31/enable');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "status": "installing"
  }
}

SSL

Certificates

Issue, inspect, renew, and remove Let’s Encrypt certificates. Certificate paths and private key paths are never exposed.

GET /sites/{siteId}/certificates

Lists SSL certificates for a site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/certificates');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 9,
      "site_id": 18,
      "provider": "letsencrypt",
      "status": "active",
      "verification_method": "dns-01",
      "key_algorithm": "ecdsa",
      "label": "Let's Encrypt",
      "domains": ["example.com", "www.example.com"],
      "issued_at": "2026-06-02T15:30:00.000000Z",
      "expires_at": "2026-08-31T15:30:00.000000Z"
    }
  ]
}
POST /sites/{siteId}/certificates

Queues a Let’s Encrypt certificate issue for a selectable site domain.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/certificates', [
    'domain' => 'example.com',
    'key_algorithm' => 'ecdsa',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 9,
    "site_id": 18,
    "provider": "letsencrypt",
    "status": "installing",
    "verification_method": "http-01",
    "domains": ["example.com", "www.example.com"]
  }
}
GET /sites/{siteId}/certificates/{certificateId}

Shows one certificate record without filesystem paths or private material.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/certificates/9');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 9,
    "provider": "letsencrypt",
    "status": "active",
    "domains": ["example.com", "www.example.com"]
  }
}
POST /sites/{siteId}/certificates/{certificateId}/renew

Queues manual renewal for a renewable certificate.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/certificates/9/renew');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 10,
    "provider": "letsencrypt",
    "status": "installing"
  }
}
DELETE /sites/{siteId}/certificates/{certificateId}

Queues certificate removal and Nginx refresh through the existing certificate manager.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/sites/18/certificates/9');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "message": "Certificate removal queued.",
  "data": {
    "id": 9,
    "status": "removing"
  }
}

Mail

Mail profiles

Create, update, activate, verify, and remove site mail profiles. Provider credentials and raw metadata are redacted.

GET /sites/{siteId}/mail-profiles

Lists mail profiles attached to a site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/mail-profiles');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 4,
      "site_id": 18,
      "provider": "mailgun",
      "status": "active",
      "is_active": true,
      "domain": "example.com",
      "from_address": "hello@example.com",
      "from_name": "Example",
      "sending_domain": "mg.example.com"
    }
  ]
}
POST /sites/{siteId}/mail-profiles

Attaches a mail provider profile to an active custom site domain and queues provider setup when needed.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/mail-profiles', [
    'provider_connection_id' => 14,
    'domain' => 'example.com',
    'from_address' => 'hello@example.com',
    'from_name' => 'Example',
    'message_stream_id' => 'outbound',
    'is_active' => true,
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 4,
    "site_id": 18,
    "status": "activating",
    "is_active": true,
    "from_address": "hello@example.com"
  }
}
GET /sites/{siteId}/mail-profiles/{mailProfileId}

Shows one mail profile without credential data.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/mail-profiles/4');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 4,
    "provider": "mailgun",
    "status": "active",
    "from_address": "hello@example.com"
  }
}
PATCH /sites/{siteId}/mail-profiles/{mailProfileId}

Updates editable mail profile fields. Provider connection cannot be changed on an existing profile.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->patch('https://forgedbase.com/api/v1/sites/18/mail-profiles/4', [
    'from_name' => 'Example Support',
    'is_active' => true,
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 4,
    "status": "active",
    "from_name": "Example Support"
  }
}
PUT /sites/{siteId}/mail-profiles/{mailProfileId}

Replaces the editable mail profile fields accepted by the update endpoint.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->put('https://forgedbase.com/api/v1/sites/18/mail-profiles/4', [
    'domain' => 'example.com',
    'from_address' => 'hello@example.com',
    'from_name' => 'Example Support',
    'message_stream_id' => 'outbound',
    'is_active' => true,
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 4,
    "status": "active"
  }
}
DELETE /sites/{siteId}/mail-profiles/{mailProfileId}

Queues provider cleanup and removal for a mail profile.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/sites/18/mail-profiles/4');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "message": "Mail profile removal queued.",
  "data": {
    "id": 4,
    "status": "removing"
  }
}
POST /sites/{siteId}/mail-profiles/{mailProfileId}/activate

Makes this profile the active sender and queues provider application if required.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/mail-profiles/4/activate');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 4,
    "is_active": true,
    "status": "active"
  }
}
POST /sites/{siteId}/mail-profiles/{mailProfileId}/verify

Queues a mail DNS/provider verification check.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/mail-profiles/4/verify');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "message": "Mail verification queued.",
  "data": {
    "id": 4,
    "status": "verifying"
  }
}

Data

Server databases

List databases, queue database creation, attach an unattached database to a site, and queue deletion. Generated database credentials are returned once on create, then redacted from read responses.

GET /servers/{serverId}/databases

Lists databases on an owned, plan-manageable server.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7/databases');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 22,
      "server_id": 7,
      "engine": "mysql",
      "name": "app_db",
      "status": "ready",
      "connection": {
        "host": "127.0.0.1",
        "port": 3306
      },
      "created_at": "2026-06-02T14:45:00.000000Z"
    }
  ]
}
POST /servers/{serverId}/databases

Queues database creation on a ready database-capable server. If username/password are omitted, ForgedBase generates them and returns the generated credentials once.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/servers/7/databases', [
    'name' => 'app_db',
    'username' => 'app_user',
]);

$data = $response->json();

Example response

Generated database credentials are returned only on this create response when ForgedBase generated the password. Save them immediately; list and show responses redact credentials.

JSON
{
  "data": {
    "id": 22,
    "server_id": 7,
    "engine": "mysql",
    "name": "app_db",
    "status": "creating",
    "connection": {
      "host": "127.0.0.1",
      "port": 3306
    },
    "credentials": {
      "database": "app_db",
      "username": "app_user",
      "password": "R7pQ9mK2xV4cL8zT6nY3sA5dF1hJ0wBq"
    }
  }
}
GET /servers/{serverId}/databases/{databaseId}

Shows one database record without username or password fields.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7/databases/22');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 22,
    "engine": "mysql",
    "name": "app_db",
    "status": "ready",
    "connection": {
      "host": "127.0.0.1",
      "port": 3306
    }
  }
}
POST /servers/{serverId}/databases/{databaseId}/attach-site

Attaches a ready, unattached database to a site on the same server. If the site already points at another database, this changes the site to use the selected database.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/servers/7/databases/22/attach-site', [
    'site_id' => 14,
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 22,
    "server_id": 7,
    "site_id": 14,
    "site_domain": "app.example.com",
    "server_database_id": 22
  }
}
DELETE /servers/{serverId}/databases/{databaseId}

Queues database deletion. Any attached sites are detached from this database before removal is queued.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/servers/7/databases/22');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 22,
    "name": "app_db",
    "status": "removing"
  }
}

Operations

Commands

Queue, inspect, and stop server/site command runs. Command output is not exposed through the public API.

GET /servers/{serverId}/command-runs

Lists server command runs with output availability only.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7/command-runs');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 55,
      "resource_type": "server",
      "server_id": 7,
      "site_id": null,
      "command": "systemctl status nginx",
      "status": "finished",
      "exit_code": 0,
      "has_output": true,
      "started_at": "2026-06-06T10:00:00.000000Z",
      "finished_at": "2026-06-06T10:00:04.000000Z"
    }
  ]
}
POST /servers/{serverId}/command-runs

Queues a root-level server command through the existing command runner.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/servers/7/command-runs', [
    'command' => 'systemctl status nginx',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 55,
    "server_id": 7,
    "site_id": null,
    "command": "systemctl status nginx",
    "status": "queued",
    "has_output": false
  }
}
GET /servers/{serverId}/command-runs/{commandRunId}

Shows one server command run. Command output remains redacted.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7/command-runs/55');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 55,
    "resource_type": "server",
    "server_id": 7,
    "command": "systemctl status nginx",
    "status": "finished",
    "exit_code": 0,
    "has_output": true
  }
}
POST /servers/{serverId}/command-runs/{commandRunId}/stop

Stops an active server command run.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/servers/7/command-runs/55/stop');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 55,
    "status": "stopped"
  }
}
GET /sites/{siteId}/command-runs

Lists site command runs with output availability only.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/command-runs');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 71,
      "resource_type": "site",
      "server_id": 7,
      "site_id": 18,
      "command": "php artisan migrate --force",
      "status": "finished",
      "exit_code": 0,
      "has_output": true
    }
  ]
}
POST /sites/{siteId}/command-runs

Queues a command in the site runtime context.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/command-runs', [
    'command' => 'php artisan migrate --force',
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 71,
    "server_id": 7,
    "site_id": 18,
    "command": "php artisan migrate --force",
    "status": "queued",
    "has_output": false
  }
}
GET /sites/{siteId}/command-runs/{commandRunId}

Shows one site command run. Command output remains redacted.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/command-runs/71');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 71,
    "resource_type": "site",
    "site_id": 18,
    "command": "php artisan migrate --force",
    "status": "finished",
    "exit_code": 0,
    "has_output": true
  }
}
POST /sites/{siteId}/command-runs/{commandRunId}/stop

Stops an active site command run.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/command-runs/71/stop');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 71,
    "status": "stopped"
  }
}

Operations

Provisioning history

Read provisioning runs for servers and sites without raw internal metadata.

GET /servers/{serverId}/provisioning-runs

Lists provisioning runs for a server.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7/provisioning-runs');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 101,
      "type": "server.provision",
      "status": "completed",
      "current_step_key": "complete",
      "current_step_label": "Complete",
      "total_steps": 12,
      "completed_steps": 12,
      "created_at": "2026-06-01T11:30:00.000000Z",
      "finished_at": "2026-06-01T12:00:00.000000Z"
    }
  ]
}
GET /sites/{siteId}/provisioning-runs

Lists provisioning runs for a site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/provisioning-runs');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 118,
      "type": "site.provision",
      "status": "completed",
      "completed_steps": 8,
      "total_steps": 8
    }
  ]
}

Release flow

Deployments

Read deployment history and trigger a deployment through the existing dispatcher.

GET /sites/{siteId}/deployments

Lists deployment provisioning runs for a site.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/deployments');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 140,
      "type": "site.deploy",
      "status": "completed",
      "current_step_label": "Deployment complete",
      "completed_steps": 5,
      "total_steps": 5,
      "created_at": "2026-06-06T09:45:00.000000Z"
    }
  ]
}
POST /sites/{siteId}/deployments

Queues a deployment and returns 202 Accepted with the queued provisioning run.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/sites/18/deployments', [
    'reference' => 'deploy-2026-06-06-001',
    'branch' => 'main',
    'metadata' => [
        'source' => 'ci',
    ],
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 141,
    "type": "site.deploy",
    "status": "queued",
    "current_step_key": "queued",
    "current_step_label": "Queued",
    "total_steps": 5,
    "completed_steps": 0,
    "created_at": "2026-06-06T10:05:00.000000Z"
  },
  "message": "Site deployment queued."
}

Audit

Activity

Read safe activity summaries. Raw context payloads and secrets are not exposed.

GET /servers/{serverId}/activities

Lists server activity messages and levels.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/servers/7/activities');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 301,
      "level": "info",
      "message": "Server provisioning completed.",
      "created_at": "2026-06-01T12:00:00.000000Z"
    }
  ]
}
GET /sites/{siteId}/activities

Lists site activity messages and levels.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/sites/18/activities');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 322,
      "level": "info",
      "message": "Site deployment queued.",
      "created_at": "2026-06-06T10:05:00.000000Z"
    }
  ]
}

Connections

Providers and repositories

Connect, update, sync, disconnect, and read provider connections. Credentials and token metadata are accepted on write only and are never returned by read endpoints.

GET /provider-connections

Lists provider accounts. Use ?type=server, source_control, storage, cloud_storage, or mail to narrow the response.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/provider-connections?type=storage');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 5,
      "provider": "github",
      "status": "connected",
      "display_name": "GitHub",
      "email": "dev@example.com",
      "external_account_id": "github-123",
      "created_at": "2026-05-30T09:00:00.000000Z"
    }
  ]
}
GET /provider-connections/{providerConnectionId}

Shows one provider connection with redacted configuration and credential state.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/provider-connections/31');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "provider": "amazon-s3",
    "provider_type": "storage",
    "status": "connected",
    "display_name": "Primary backups",
    "configuration": {
      "bucket": "forgedbase-backups",
      "region": "eu-west-1",
      "path_prefix": "daily",
      "default_for_backups": true
    }
  }
}
POST /provider-connections

Connects a provider that supports API credential/config based setup. Browser OAuth providers such as GitHub and GitLab are connected in the dashboard, then managed here.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/provider-connections', [
    'provider' => 'amazon-s3',
    'display_name' => 'Primary backups',
    'storage' => [
        'bucket' => 'forgedbase-backups',
        'region' => 'eu-west-1',
        'path_prefix' => 'daily',
    ],
    'credentials' => [
        'access_key_id' => 'YOUR_ACCESS_KEY_ID',
        'secret_access_key' => 'YOUR_SECRET_ACCESS_KEY',
    ],
    'default_for_backups' => true,
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "provider": "amazon-s3",
    "provider_type": "storage",
    "status": "connected",
    "display_name": "Primary backups",
    "configuration": {
      "bucket": "forgedbase-backups",
      "region": "eu-west-1",
      "path_prefix": "daily",
      "default_for_backups": true
    }
  },
  "message": "Provider connected."
}
PATCH /provider-connections/{providerConnectionId}

Updates display name and editable configuration. Omit unchanged secrets; stored credentials are preserved.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->patch('https://forgedbase.com/api/v1/provider-connections/31', [
    'display_name' => 'Nightly backups',
    'storage' => [
        'bucket' => 'forgedbase-backups',
        'region' => 'eu-west-1',
        'path_prefix' => 'nightly',
    ],
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "provider": "amazon-s3",
    "status": "connected",
    "display_name": "Nightly backups",
    "configuration": {
      "bucket": "forgedbase-backups",
      "region": "eu-west-1",
      "path_prefix": "nightly"
    }
  },
  "message": "Provider updated."
}
PUT /provider-connections/{providerConnectionId}

Replaces editable provider configuration. Use the same body shape as PATCH when you want a full configuration update.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->put('https://forgedbase.com/api/v1/provider-connections/31', [
    'display_name' => 'Primary backups',
    'storage' => [
        'bucket' => 'forgedbase-backups',
        'region' => 'eu-west-1',
        'path_prefix' => 'daily',
    ],
    'default_for_backups' => true,
]);

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "provider": "amazon-s3",
    "status": "connected",
    "display_name": "Primary backups"
  },
  "message": "Provider updated."
}
DELETE /provider-connections/{providerConnectionId}

Disconnects a provider connection and returns the disconnected record.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/provider-connections/31');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "provider": "amazon-s3",
    "status": "disconnected"
  },
  "message": "Provider disconnected."
}
POST /provider-connections/{providerConnectionId}/sync

Queues server-provider metadata sync or source-control repository sync, depending on provider type.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/provider-connections/5/sync');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 5,
    "provider": "github",
    "status": "syncing",
    "last_sync_started_at": "2026-06-06T13:40:00.000000Z"
  },
  "message": "Provider sync queued."
}
POST /provider-connections/{providerConnectionId}/disconnect

Disconnects a provider connection and returns the disconnected record. DELETE /provider-connections/{providerConnectionId} performs the same disconnect action.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->post('https://forgedbase.com/api/v1/provider-connections/31/disconnect');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 31,
    "provider": "amazon-s3",
    "status": "disconnected"
  },
  "message": "Provider disconnected."
}
GET /provider-connections/{providerConnectionId}/repositories

Lists synced repositories for a provider connection.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/provider-connections/5/repositories');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 88,
      "provider_connection_id": 5,
      "owner": "acme",
      "name": "site",
      "full_name": "acme/site",
      "default_branch": "main",
      "is_private": true,
      "html_url": "https://github.com/acme/site"
    }
  ]
}
GET /provider-connections/{providerConnectionId}/repositories/{repositoryId}

Shows one synced repository for a provider connection.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/provider-connections/5/repositories/88');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 88,
    "provider_connection_id": 5,
    "owner": "acme",
    "name": "site",
    "full_name": "acme/site",
    "default_branch": "main",
    "is_private": true,
    "html_url": "https://github.com/acme/site"
  }
}

Connections

Integrations

Read connected integration state and disconnect integrations. Credentials and webhook URLs are redacted; integration creation stays with the dashboard-specific OAuth/verification flows.

GET /integrations

Lists integration connections with plan availability.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/integrations');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": [
    {
      "id": 14,
      "integration": "slack",
      "status": "connected",
      "display_name": "Launch alerts",
      "external_account_id": "slack-team-1",
      "plan_allowed": true,
      "created_at": "2026-06-01T08:30:00.000000Z"
    }
  ]
}
GET /integrations/{integrationConnectionId}

Shows one integration connection when the current plan allows it.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://forgedbase.com/api/v1/integrations/14');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "data": {
    "id": 14,
    "integration": "slack",
    "status": "connected",
    "display_name": "Launch alerts",
    "plan_allowed": true
  }
}
DELETE /integrations/{integrationConnectionId}

Queues integration disconnection through the existing dashboard integration manager.

Example request

Send this request with a scoped API key.

use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->delete('https://forgedbase.com/api/v1/integrations/14');

$data = $response->json();

Example response

Responses use stable JSON envelopes and omit credentials, secrets, and raw internal payloads.

JSON
{
  "message": "Integration disconnection queued.",
  "data": {
    "id": 14,
    "integration": "slack",
    "status": "removing"
  }
}

Access scopes

API abilities

Abilities are the scopes you choose when creating an API key. They limit what the bearer token may do, while workspace ownership, user permissions, plan limits, and resource manageability still apply.

Machine-readable discovery

Use this endpoint from scripts or custom clients that need to sync the current ability list.

https://forgedbase.com/api/v1/abilities

API

1 ability

*

All API abilities

Wildcard

Providers

4 abilities

providers.view

View providers

providers.connect

Connect providers

providers.sync

Sync providers

providers.disconnect

Disconnect providers

Source control providers

4 abilities

source-control-providers.view

View source control providers

source-control-providers.connect

Connect source control providers

source-control-providers.sync

Sync source control providers

source-control-providers.disconnect

Disconnect source control providers

Storage providers

3 abilities

storage-providers.view

View storage providers

storage-providers.connect

Connect storage providers

storage-providers.disconnect

Disconnect storage providers

File transfers

1 ability

file-transfers.manage

Manage file transfers

Mail providers

3 abilities

mail-providers.view

View mail providers

mail-providers.connect

Connect mail providers

mail-providers.disconnect

Disconnect mail providers

Servers

9 abilities

servers.view

View servers

servers.create

Create servers

servers.manage

Manage servers

servers.protection

Manage server protection

servers.delete

Delete servers

servers.commands

Run server commands

servers.console-root

Access root console

databases.manage

Manage databases

backups.manage

Manage backups

Sites

6 abilities

sites.view

View sites

sites.create

Create sites

sites.manage

Manage sites

sites.deploy

Deploy sites

sites.delete

Delete sites

domains.manage

Manage domains and SSL

Access

3 abilities

ssh-keys.manage

Manage SSH keys

sftp.manage

Manage SFTP access

deploy-keys.manage

Manage deploy keys

Integrations

3 abilities

integrations.view

View integrations

integrations.create

Create integrations

integrations.disconnect

Disconnect integrations

Account

2 abilities

team.manage

Manage team

settings.manage

Manage billing and settings

Security

Redaction and access rules

The public API intentionally exposes operational summaries, not raw secrets or internal payloads.

Full API keys are shown once at creation and are stored only as hashes afterward.

Token prefixes are safe for identification, but full bearer tokens are never returned by list or show endpoints.

Provider credentials, token metadata, certificate paths, private key paths, command output, raw activity context, and secret payloads are intentionally redacted. Generated database credentials are returned once on database creation, then redacted from read responses.

API abilities never bypass workspace ownership, user permissions, plan restrictions, or resource manageability checks.

Destructive API resource deletion is not exposed except API key record deletion through authenticated settings access.

Ready to automate ForgedBase?

Create a scoped API key, inspect the OpenAPI document, and start with read endpoints before queuing deployment automation.

Get started