Playbooks API

Account intelligence for GTM engineers. Enrich any company with initiative-level signals, technology context, pressure points, and strategic gaps — sourced from job postings, team profiles, and public filings.

Playbooks goes beyond standard firmographic enrichment. Instead of flat data fields, you get structured intelligence about what a company is actively building, where their operational pressure is, and what initiatives they haven’t started yet. Each signal includes confidence levels, evidence sources, and explicit caveats about what the data does and doesn’t tell you.

Base URL: All API requests should be made to https://api.playbooks.uk

Authentication

Authenticate by including your API key in the Authorization header of every request. Keys are prefixed with pb_ for easy identification.

curl https://api.playbooks.uk/v1/enrich \
  -H "Authorization: Bearer pb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"linkedin_url": "https://www.linkedin.com/company/example"}'

Your API key carries access privileges — keep it secure. Don’t share it in client-side code, public repositories, or URLs.

Rate limits

Rate limits are applied per API key. Current limits are included in response headers.

LimitDefaultHeader
Per day100 requestsX-RateLimit-Remaining-Daily
Per minute10 requestsX-RateLimit-Remaining-Minute

Need higher limits? Contact us to discuss volume pricing.

Errors

Playbooks uses conventional HTTP status codes. All errors return a JSON body with error and message fields.

CodeMeaning
200Enrichment succeeded
202Enrichment accepted — processing asynchronously
400Bad request — missing or invalid parameters
401No API key provided
403Invalid API key
429Rate limit exceeded
502Enrichment pipeline error — retry the request
// Error response format
{
  "error": "invalid_linkedin_url",
  "message": "Provide a valid LinkedIn company page URL.",
  "example": "https://www.linkedin.com/company/general-dynamics"
}

Submit enrichment

POST /v1/enrich

Submit a company for enrichment. Returns a job ID immediately. Processing takes 3–5 minutes.

Async processing. Playbooks performs deep intelligence gathering that takes 3–5 minutes per account. Submit your request, receive a job ID, then either poll the status endpoint or provide a callback_url to receive results automatically.

Request body

ParameterTypeDescription
linkedin_urlstringRequiredLinkedIn company page URL
callback_urlstringOptionalURL to receive results via webhook when processing completes. Results are POSTed as JSON.

Example request

curl -X POST https://api.playbooks.uk/v1/enrich \
  -H "Authorization: Bearer pb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "linkedin_url": "https://www.linkedin.com/company/general-dynamics-mission-systems",
    "callback_url": "https://your-app.com/webhook/playbooks"
  }'

Response (202 Accepted)

{
  "success": true,
  "job_id": "job_a1b2c3d4e5f6...",
  "status": "processing",
  "linkedin_url": "https://www.linkedin.com/company/general-dynamics-mission-systems",
  "message": "Enrichment started. Results will be sent to your callback URL when ready.",
  "poll_url": "https://api.playbooks.uk/v1/enrich/job_a1b2c3d4e5f6..."
}

Callback delivery

If you provide a callback_url, Playbooks will POST the results to your URL when processing completes. The payload includes the full enrichment data, status, and metadata.

// Callback payload delivered to your URL
{
  "job_id": "job_a1b2c3d4e5f6...",
  "status": "success",
  "message": "Enrichment completed successfully for https://...",
  "linkedin_url": "https://www.linkedin.com/company/general-dynamics-mission-systems",
  "created_at": "2026-03-04T14:32:00.000Z",
  "completed_at": "2026-03-04T14:36:42.000Z",
  "data": {
    "tooling_in_context": { /* ... */ },
    "current_state": { /* ... */ },
    "initiatives": { /* ... */ }
  }
}

Check enrichment status

GET /v1/enrich/{job_id}

Check the status of an enrichment job and retrieve results when complete.

Enrichment statuses

StatusMeaningBillable
processingStill running. Poll again in 30–60 seconds.No
successFull intelligence report generated.Yes
insufficient_dataCompleted but limited public data available. Partial results may be included.Yes
bad_urlLinkedIn URL could not be resolved to a valid company page.No
failedProcessing error. Retry the request.No

Example: Poll until complete

curl https://api.playbooks.uk/v1/enrich/job_a1b2c3d4e5f6... \
  -H "Authorization: Bearer pb_your_api_key"

Response (still processing)

{
  "job_id": "job_a1b2c3d4e5f6...",
  "status": "processing",
  "linkedin_url": "https://www.linkedin.com/company/general-dynamics-mission-systems",
  "message": "Still processing. Try again in 30-60 seconds."
}

Response (completed)

{
  "job_id": "job_a1b2c3d4e5f6...",
  "status": "success",
  "message": "Enrichment completed successfully for https://...",
  "linkedin_url": "https://www.linkedin.com/company/general-dynamics-mission-systems",
  "created_at": "2026-03-04T14:32:00.000Z",
  "completed_at": "2026-03-04T14:36:42.000Z",
  "data": {
    "tooling_in_context": { /* ... */ },
    "current_state": { /* ... */ },
    "initiatives": { /* ... */ }
  }
}

Response (bad URL)

{
  "job_id": "job_a1b2c3d4e5f6...",
  "status": "bad_url",
  "message": "The LinkedIn URL provided could not be resolved to a valid company page. Please check the URL and resubmit.",
  "linkedin_url": "https://www.linkedin.com/company/invalid-company"
}

Batch enrich

POST /v1/enrich/batch

Enrich up to 25 accounts in a single request. Each account is processed asynchronously and returns a job ID.

Request body

ParameterTypeDescription
accountsarrayRequiredArray of objects, each with a linkedin_url field. Max 25.
callback_urlstringOptionalURL to receive results for each account as they complete.

Example request

curl -X POST https://api.playbooks.uk/v1/enrich/batch \
  -H "Authorization: Bearer pb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "callback_url": "https://your-app.com/webhook/playbooks",
    "accounts": [
      { "linkedin_url": "https://www.linkedin.com/company/ford-motor-company" },
      { "linkedin_url": "https://www.linkedin.com/company/verizon" },
      { "linkedin_url": "https://www.linkedin.com/company/boston-scientific" }
    ]
  }'

Response (202 Accepted)

{
  "success": true,
  "message": "3 enrichment jobs started.",
  "jobs": [
    { "linkedin_url": "https://www.linkedin.com/company/ford-motor-company", "job_id": "job_a1b2...", "status": "processing" },
    { "linkedin_url": "https://www.linkedin.com/company/verizon", "job_id": "job_c3d4...", "status": "processing" },
    { "linkedin_url": "https://www.linkedin.com/company/boston-scientific", "job_id": "job_e5f6...", "status": "processing" }
  ]
}

List jobs

GET /v1/jobs

List your most recent enrichment jobs (up to 50).

curl https://api.playbooks.uk/v1/jobs \
  -H "Authorization: Bearer pb_your_api_key"
{
  "jobs": [
    {
      "job_id": "job_a1b2c3d4e5f6...",
      "status": "completed",
      "linkedin_url": "https://www.linkedin.com/company/ford-motor-company",
      "created_at": "2026-03-04T14:32:00.000Z",
      "completed_at": "2026-03-04T14:36:42.000Z"
    }
  ]
}

Usage stats

GET /v1/usage

View your current rate limits, credit usage, and recent requests.

curl https://api.playbooks.uk/v1/usage \
  -H "Authorization: Bearer pb_your_api_key"
{
  "customer": "Acme Corp",
  "rate_limits": {
    "today": {
      "requests": 12,
      "limit": 100,
      "remaining": 88
    }
  },
  "credits": {
    "current_month": "2026-03",
    "usage": {
      "total": 47,
      "success": 42,
      "insufficient_data": 5
    },
    "history": [],
    "persistent": true
  },
  "recentRequests": [ /* last 20 requests */ ]
}

Only success and insufficient_data statuses count as billable credits. failed and bad_url statuses are not billed.

Response schema

Every enrichment returns three intelligence layers, each designed for a specific question a GTM engineer needs answered.

tooling_in_context

What technologies and platforms are confirmed or indicated at this company. Each entry includes a confidence level and evidence sources.

FieldTypeDescription
technologystringTechnology or platform name
usageTypeenumconfirmed_usage or required_expertise
confidenceenumhigh, medium, or low
notesstringContext on what the evidence does and doesn’t tell you
evidenceUrlsarraySource URLs supporting this finding
relationshipToTopicstringHow this technology relates to the topic lens

current_state

Operational reality — pressure points, org signals, and critically, uncertainties and gaps. The gaps are often more valuable for outreach than the confirmed findings.

FieldTypeDescription
environmentOverviewstringNarrative summary of the technology environment
pressurePointsarrayOperational pressures and pain indicators with confidence
organizationalSignalsarrayTeam structure, operating model, and scale signals
operationalCharacteristicsarrayHow they operate — support models, deployment patterns
uncertaintiesAndGapsarrayWhat we don’t know — and why that matters for your outreach

initiatives

What they’re actively building toward and what they haven’t started. Includes initiative classification, evidence, key uncertainties, and explicit non-findings.

FieldTypeDescription
initiatives[]arrayActive and emerging initiatives
.initiativestringInitiative name
.initiativeTypeenumplatform_build, capability_building, governance
.scopeenumorg-wide, divisional, team-level
.confidenceenumhigh, medium, low
.primaryEvidencearraySource evidence with URLs and reasoning
.keyUncertaintiesarrayWhat’s still unclear — conversation hooks
explicitNonFindingsarrayThings we looked for and did not find evidence of
futureStateSummarystringNarrative overview of where the company is heading
A note on confidence levels. Unlike most enrichment tools, Playbooks explicitly tells you what it doesn’t know. Low-confidence signals and explicit non-findings aren’t failures — they’re conversation hooks. “We found no evidence of centralised certificate management” is a better outreach angle than “they use Kubernetes.”

Clay integration

Use Playbooks as an enrichment step in any Clay table via the HTTP API integration.

Sending enrichment requests

In your Clay table, add an HTTP API enrichment step:

SettingValue
MethodPOST
URLhttps://api.playbooks.uk/v1/enrich
HeadersAuthorization: Bearer pb_your_api_key
Content-Type: application/json
Body{"linkedin_url": "{{linkedin_company_url}}", "callback_url": "https://api.clay.com/v3/sources/webhook/your-webhook-id"}

Receiving results

Create a second Clay table with a webhook source. Set the callback_url in your enrichment request to your Clay webhook URL. Results arrive automatically when processing completes — no polling needed.

Useful field mappings

Clay columnJSON path
Environment Summarydata.current_state.environmentOverview
Top Pressure Pointdata.current_state.pressurePoints[0].pressure
Top Initiativedata.initiatives.initiatives[0].initiative
Key Gapsdata.initiatives.explicitNonFindings
Future Statedata.initiatives.futureStateSummary

Quickstart

Python

import requests

response = requests.post(
    "https://api.playbooks.uk/v1/enrich",
    headers={
        "Authorization": "Bearer pb_your_api_key",
        "Content-Type": "application/json",
    },
    json={
        "linkedin_url": "https://www.linkedin.com/company/ford-motor-company",
        "callback_url": "https://your-app.com/webhook",
    },
)

job = response.json()
print(f"Job started: {job['job_id']}")
print(f"Poll at: {job['poll_url']}")

# Poll for results
import time
while True:
    result = requests.get(
        f"https://api.playbooks.uk/v1/enrich/{job['job_id']}",
        headers={"Authorization": "Bearer pb_your_api_key"},
    ).json()
    if result["status"] != "processing":
        break
    time.sleep(30)

# Get the top initiative
top = result["data"]["initiatives"]["initiatives"][0]
print(f"Top initiative: {top['initiative']} ({top['confidence']})")

# Get gaps — your best outreach angles
gaps = result["data"]["initiatives"]["explicitNonFindings"]
for gap in gaps:
    print(f"Gap: {gap}")

JavaScript / Node.js

// Submit enrichment
const response = await fetch("https://api.playbooks.uk/v1/enrich", {
  method: "POST",
  headers: {
    "Authorization": "Bearer pb_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    linkedin_url: "https://www.linkedin.com/company/ford-motor-company",
    callback_url: "https://your-app.com/webhook",
  }),
});

const job = await response.json();
console.log(`Job started: ${job.job_id}`);

// Poll for results
let result;
do {
  await new Promise(r => setTimeout(r, 30000));
  const res = await fetch(`https://api.playbooks.uk/v1/enrich/${job.job_id}`, {
    headers: { "Authorization": "Bearer pb_your_api_key" },
  });
  result = await res.json();
} while (result.status === "processing");

// Pressure points — what's hurting them
result.data.current_state.pressurePoints.forEach(p =>
  console.log(`${p.pressure} (${p.confidence})`)
);

// Explicit non-findings — your outreach angles
result.data.initiatives.explicitNonFindings.forEach(gap =>
  console.log(`Gap: ${gap}`)
);

Need help? Contact us at vish@playbooks.uk for onboarding, custom integrations, or volume pricing.