Catalog API

Read catalog products, product plans, and related product metadata from the protected Plandalf API.

The Catalog API exposes the product records Plandalf uses around offers, pricing, invoices, and checkout context.

Current write status

Product create, update, and delete routes exist in the Laravel resource registration, but the current controller methods and form requests do not implement public write behavior. Treat catalog product writes as dashboard-managed or integration-managed until the API exposes validated write requests.

Endpoints

Authentication

Use a bearer API key or OAuth token. The API resolves the current organization from the authenticated user context.

Authorization: Bearer <api_key_or_oauth_token>
Accept: application/json
Content-Type: application/json

List products

Endpoint

List products

Returns paginated catalog products for the authenticated user's current organization.

GET /api/catalog/products
Base URL
https://api.plandalf.com
Authentication
Bearer token
Operation ID
listCatalogProducts
Request URL
https://api.plandalf.com/api/catalog/products

Query parameters

queryper_pageintegerdefault: 250

Maximum number of products per page. The controller reads this as per_page and defaults to 250.

List catalog products

Request
curl "https://api.plandalf.com/api/catalog/products?per_page=100" \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Accept: application/json"

Response fields

dataarray

Product resources for the current page.

Product list response

Response
{
  "data": [
    {
      "id": "prod_01h...",
      "name": "Pro plan",
      "display_name": "Pro plan",
      "description": "Annual access",
      "family": {
        "id": "family_01h...",
        "name": "Membership",
        "lookup_key": "membership"
      },
      "version_number": 1,
      "status": "active",
      "published_at": 1718846400,
      "archived_at": null
    }
  ],
  "links": {
    "first": "https://api.plandalf.com/api/catalog/products?page=1",
    "last": null,
    "prev": null,
    "next": null
  }
}

Retrieve a product

Endpoint

Retrieve a product

Returns one catalog product. Product features are loaded when the controller resolves the product.

GET /api/catalog/products/{product}
Base URL
https://api.plandalf.com
Authentication
Bearer token
Operation ID
retrieveCatalogProduct
Request URL
https://api.plandalf.com/api/catalog/products/{product}

Path parameters

pathproductstringrequired

Product route key. Use the id returned by the product list.

Retrieve one product

Request
curl "https://api.plandalf.com/api/catalog/products/prod_01h..." \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Accept: application/json"

Product response

Response
{
  "id": "prod_01h...",
  "name": "pro-plan",
  "display_name": "Pro plan",
  "description": "Annual access",
  "family": {
    "id": "family_01h...",
    "name": "Membership",
    "lookup_key": "membership"
  },
  "version_number": 1,
  "features": [],
  "twins": [],
  "status": "active",
  "published_at": 1718846400,
  "archived_at": null
}

Response fields

idstring

Public product route key.

namestring | null

Internal or source-system product name.

display_namestring | null

Customer-facing display name when one is set.

descriptionstring | null

Product description copied from the source system or edited in Plandalf.

created_atinteger | null

Unix timestamp for product creation.

updated_atinteger | null

Unix timestamp for the last product update.

familyobject | null

Product family metadata when the productFamily relation is loaded.

version_numberinteger | null

Version marker from the catalog product model.

featuresarray

Product feature records when productFeatures.feature is loaded by the show controller.

twinsarray

Linked provider records when external twins are loaded.

statusstring | null

Product status, such as active or archived.

published_atinteger | null

Unix timestamp for publication when the product is published.

archived_atinteger | null

Unix timestamp for archival when the product is archived.

List product plans

Endpoint

List product plans

Returns the pricing plans attached to a catalog product.

GET /api/catalog/products/{product}/plans
Base URL
https://api.plandalf.com
Authentication
Bearer token
Operation ID
listCatalogProductPlans
Request URL
https://api.plandalf.com/api/catalog/products/{product}/plans

Path parameters

pathproductstringrequired

Product route key.

List product plans

Request
curl "https://api.plandalf.com/api/catalog/products/prod_01h.../plans" \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Accept: application/json"

Response fields

dataarray

Plan resources attached to the product.

idstring

Public plan route key.

objectstring

Resource type. Product plan resources return plan.

statusstring | null

Current plan status.

typestring | null

Plan type, such as recurring.

renew_intervalstring | null

ISO 8601 interval string when the plan renews.

chargesarray

Loaded charge resources for the plan.

Product plan shape

Response
{
  "id": "plan_01h...",
  "object": "plan",
  "status": "active",
  "type": "recurring",
  "display_name": "Annual",
  "description": "Annual access",
  "name": "annual",
  "renew_interval": "P1Y",
  "billing_anchor": "anniversary",
  "invoice_interval": "P1Y",
  "currency_code": "USD",
  "currency_symbol": "$"
}

Write behavior

Use the dashboard for writes

The current ProductsController has resource methods for store, update, and destroy, but those methods are empty and their form requests currently return authorize(): false. Do not build production automation against product write routes yet.

Read-only catalog flow

const response = await fetch("https://api.plandalf.com/api/catalog/products", {
  headers: {
    Authorization: `Bearer ${process.env.PLANDALF_API_KEY}`,
    Accept: "application/json"
  }
});

const products = await response.json();
curl "https://api.plandalf.com/api/catalog/products" \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Accept: application/json"

Feature detail