php-framework/docs/api/endpoints.md

13 KiB

API Endpoints Reference

Core PHP Framework provides RESTful APIs for programmatic access to platform resources. All endpoints follow consistent patterns for authentication, pagination, filtering, and error handling.

Base URL

https://your-domain.com/api/v1

Common Parameters

Pagination

All list endpoints support pagination:

GET /api/v1/resources?page=2&per_page=50

Parameters:

  • page (integer) - Page number (default: 1)
  • per_page (integer) - Items per page (default: 15, max: 100)

Response includes:

{
  "data": [...],
  "meta": {
    "current_page": 2,
    "per_page": 50,
    "total": 250,
    "last_page": 5
  },
  "links": {
    "first": "https://api.example.com/resources?page=1",
    "last": "https://api.example.com/resources?page=5",
    "prev": "https://api.example.com/resources?page=1",
    "next": "https://api.example.com/resources?page=3"
  }
}

Filtering

Filter list results using query parameters:

GET /api/v1/resources?status=active&created_after=2024-01-01

Common filters:

  • status - Filter by status (varies by resource)
  • created_after - ISO 8601 date
  • created_before - ISO 8601 date
  • updated_after - ISO 8601 date
  • updated_before - ISO 8601 date
  • search - Full-text search (if supported)

Sorting

Sort results using the sort parameter:

GET /api/v1/resources?sort=-created_at,name
  • Prefix with - for descending order
  • Default is ascending order
  • Comma-separate multiple sort fields

Field Selection

Request specific fields only:

GET /api/v1/resources?fields=id,name,created_at

Reduces payload size and improves performance.

Includes

Eager-load related resources:

GET /api/v1/resources?include=owner,tags,metadata

Reduces number of API calls needed.

Rate Limiting

API requests are rate-limited based on your tier:

Tier Requests/Hour Burst
Free 1,000 50
Pro 10,000 200
Business 50,000 500
Enterprise Custom Custom

Rate limit headers included in every response:

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9847
X-RateLimit-Reset: 1640995200

When rate limit is exceeded, you'll receive a 429 Too Many Requests response:

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please retry after 3600 seconds.",
    "retry_after": 3600
  }
}

Idempotency

POST, PATCH, PUT, and DELETE requests support idempotency keys to safely retry requests:

POST /api/v1/resources
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

If the same idempotency key is used within 24 hours:

  • Same status code and response body returned
  • No duplicate resource created
  • Safe to retry failed requests

Versioning

The API version is included in the URL path:

/api/v1/resources

When breaking changes are introduced, a new version will be released (e.g., /api/v2/). Previous versions are supported for at least 12 months after deprecation notice.

Workspaces & Namespaces

Multi-tenant resources require workspace and/or namespace context:

GET /api/v1/resources
X-Workspace-ID: 123
X-Namespace-ID: 456

Alternatively, use query parameters:

GET /api/v1/resources?workspace_id=123&namespace_id=456

See Namespaces & Entitlements for details on multi-tenancy.

Webhook Events

Configure webhooks to receive real-time notifications:

POST /api/v1/webhooks
{
  "url": "https://your-app.com/webhooks",
  "events": ["resource.created", "resource.updated"],
  "secret": "whsec_abc123..."
}

Common events:

  • {resource}.created - Resource created
  • {resource}.updated - Resource updated
  • {resource}.deleted - Resource deleted

Webhook payload:

{
  "id": "evt_1234567890",
  "type": "resource.created",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "object": {
      "id": "res_abc123",
      "type": "resource",
      "attributes": {...}
    }
  }
}

Webhook requests include HMAC-SHA256 signature in headers:

X-Webhook-Signature: sha256=abc123...
X-Webhook-Timestamp: 1640995200

See Webhook Security for signature verification.

Error Handling

All errors follow a consistent format. See Error Reference for details.

Example error response:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "email": ["The email field is required."]
    },
    "request_id": "req_abc123"
  }
}

Resource Endpoints

Core Resources

The following resource types are available:

  • Workspaces - Multi-tenant workspaces
  • Namespaces - Service isolation contexts
  • Users - User accounts
  • API Keys - API authentication credentials
  • Webhooks - Webhook endpoints

Workspace Endpoints

List Workspaces

GET /api/v1/workspaces

Response:

{
  "data": [
    {
      "id": "wks_abc123",
      "name": "Acme Corporation",
      "slug": "acme-corp",
      "tier": "business",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ]
}

Get Workspace

GET /api/v1/workspaces/{workspace_id}

Response:

{
  "data": {
    "id": "wks_abc123",
    "name": "Acme Corporation",
    "slug": "acme-corp",
    "tier": "business",
    "settings": {
      "timezone": "UTC",
      "locale": "en_GB"
    },
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  }
}

Create Workspace

POST /api/v1/workspaces

Request:

{
  "name": "New Workspace",
  "slug": "new-workspace",
  "tier": "pro"
}

Response: 201 Created

Update Workspace

PATCH /api/v1/workspaces/{workspace_id}

Request:

{
  "name": "Updated Name",
  "settings": {
    "timezone": "Europe/London"
  }
}

Response: 200 OK

Delete Workspace

DELETE /api/v1/workspaces/{workspace_id}

Response: 204 No Content

Namespace Endpoints

List Namespaces

GET /api/v1/namespaces

Query parameters:

  • owner_type - Filter by owner type (User or Workspace)
  • workspace_id - Filter by workspace
  • is_active - Filter by active status

Response:

{
  "data": [
    {
      "id": "ns_abc123",
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Personal Namespace",
      "slug": "personal",
      "owner_type": "User",
      "owner_id": 42,
      "workspace_id": null,
      "is_default": true,
      "is_active": true,
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Get Namespace

GET /api/v1/namespaces/{namespace_id}

Response:

{
  "data": {
    "id": "ns_abc123",
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Client: Acme Corp",
    "slug": "client-acme",
    "owner_type": "Workspace",
    "owner_id": 10,
    "workspace_id": 10,
    "packages": [
      {
        "id": "pkg_starter",
        "name": "Starter Package",
        "expires_at": null
      }
    ],
    "entitlements": {
      "storage": {
        "used": 1024000000,
        "limit": 5368709120,
        "unit": "bytes"
      },
      "api_calls": {
        "used": 5430,
        "limit": 10000,
        "reset_at": "2024-02-01T00:00:00Z"
      }
    }
  }
}

Check Entitlement

POST /api/v1/namespaces/{namespace_id}/entitlements/check

Request:

{
  "feature": "storage",
  "quantity": 1073741824
}

Response:

{
  "allowed": false,
  "reason": "LIMIT_EXCEEDED",
  "message": "Storage limit exceeded. Used: 1.00 GB, Available: 0.50 GB, Requested: 1.00 GB",
  "current_usage": 1024000000,
  "limit": 5368709120,
  "available": 536870912
}

User Endpoints

List Users

GET /api/v1/users
X-Workspace-ID: 123

Response:

{
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "tier": "pro",
      "email_verified_at": "2024-01-01T12:00:00Z",
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Get Current User

GET /api/v1/user

Returns the authenticated user.

Update User

PATCH /api/v1/users/{user_id}

Request:

{
  "name": "Jane Doe",
  "email": "jane@example.com"
}

API Key Endpoints

List API Keys

GET /api/v1/api-keys

Response:

{
  "data": [
    {
      "id": "key_abc123",
      "name": "Production API Key",
      "prefix": "sk_live_",
      "last_used_at": "2024-01-15T10:30:00Z",
      "expires_at": null,
      "scopes": ["read:all", "write:resources"],
      "rate_limit_tier": "business",
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Create API Key

POST /api/v1/api-keys

Request:

{
  "name": "New API Key",
  "scopes": ["read:all"],
  "rate_limit_tier": "pro",
  "expires_at": "2025-01-01T00:00:00Z"
}

Response:

{
  "data": {
    "id": "key_abc123",
    "name": "New API Key",
    "key": "sk_live_abc123def456...",
    "scopes": ["read:all"],
    "created_at": "2024-01-15T10:30:00Z"
  }
}

⚠️ Important: The key field is only returned once during creation. Store it securely.

Revoke API Key

DELETE /api/v1/api-keys/{key_id}

Response: 204 No Content

Webhook Endpoints

List Webhooks

GET /api/v1/webhooks

Response:

{
  "data": [
    {
      "id": "wh_abc123",
      "url": "https://your-app.com/webhooks",
      "events": ["resource.created", "resource.updated"],
      "is_active": true,
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Create Webhook

POST /api/v1/webhooks

Request:

{
  "url": "https://your-app.com/webhooks",
  "events": ["resource.created"],
  "secret": "whsec_abc123..."
}

Test Webhook

POST /api/v1/webhooks/{webhook_id}/test

Sends a test event to the webhook URL.

Response:

{
  "success": true,
  "status_code": 200,
  "response_time_ms": 145
}

Webhook Deliveries

GET /api/v1/webhooks/{webhook_id}/deliveries

View delivery history and retry failed deliveries:

{
  "data": [
    {
      "id": "del_abc123",
      "event_type": "resource.created",
      "status": "success",
      "status_code": 200,
      "attempts": 1,
      "delivered_at": "2024-01-15T10:30:00Z"
    }
  ]
}

Best Practices

1. Use Idempotency Keys

Always use idempotency keys for create/update operations:

const response = await fetch('/api/v1/resources', {
  method: 'POST',
  headers: {
    'Idempotency-Key': crypto.randomUUID(),
    'Authorization': `Bearer ${apiKey}`
  },
  body: JSON.stringify(data)
});

2. Handle Rate Limits

Respect rate limit headers and implement exponential backoff:

async function apiRequest(url, options) {
  const response = await fetch(url, options);

  if (response.status === 429) {
    const retryAfter = response.headers.get('X-RateLimit-Reset');
    await sleep(retryAfter * 1000);
    return apiRequest(url, options); // Retry
  }

  return response;
}

3. Use Field Selection

Request only needed fields to reduce payload size:

GET /api/v1/resources?fields=id,name,status

4. Batch Operations

When possible, use batch endpoints instead of multiple single requests:

POST /api/v1/resources/batch
{
  "operations": [
    {"action": "create", "data": {...}},
    {"action": "update", "id": "res_123", "data": {...}}
  ]
}

5. Verify Webhook Signatures

Always verify webhook signatures to ensure authenticity:

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload);
  const expected = 'sha256=' + hmac.digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

6. Store API Keys Securely

  • Never commit API keys to version control
  • Use environment variables or secrets management
  • Rotate keys regularly
  • Use separate keys for development/production

7. Monitor Usage

Track your API usage to avoid hitting rate limits:

GET /api/v1/usage

Returns current usage statistics for your account.

SDKs & Libraries

Official SDKs available:

  • PHP: composer require core-php/sdk
  • JavaScript/Node.js: npm install @core-php/sdk
  • Python: pip install core-php-sdk

Example (PHP):

use CorePhp\SDK\Client;

$client = new Client('sk_live_abc123...');

$workspace = $client->workspaces->create([
    'name' => 'My Workspace',
    'tier' => 'pro',
]);

$namespaces = $client->namespaces->list([
    'workspace_id' => $workspace->id,
]);

Further Reading