Claude Skills

Claude Skills

Claude Skills

Claude skill - Pipeline

Claude skill - Pipeline

Claude skill - Pipeline

Manage dynamic CRM pipelines in Dalil AI — discover available pipelines, retrieve their fields and stages, and create/update/delete pipeline records. Endpoints are dynamic (namePlural varies per pipeline); always discover before operating.

Dalil AI: Pipeline API Skills

Quick Reference

  • Base URL: https://app.usedalil.ai

  • Auth: Authorization: Bearer {apiKey}

  • Content-Type: application/json (POST/PATCH requests only)

  • Accept: application/json (GET requests)

  • Resource path: /rest/{namePlural} (dynamic per pipeline)

GraphQL search (POST /graphql):

  • Uses searchPipeline query (NOT search) — requires both searchInput: String! and nameSingular: String! variables

  • searchInput is a plain String! variable — do NOT pass as an object (causes type error)

  • limit must be hardcoded in the query string — do NOT pass as a $limit variable (causes type error)

  • Returns IDs only — always follow up with REST to fetch full records

Important: Dynamic Endpoints

Pipeline endpoints are NOT fixed. Each pipeline has its own namePlural (e.g., startupFundraisings, salesPipelines). You MUST discover available pipelines first.

Discovery (Required First Step)

List all pipelines

Get pipeline fields

Endpoints

Operation

Method

Path

Required Fields

Create

POST

/rest/{namePlural}

recordId (parent)

Get

GET

/rest/{namePlural}/{id}

id (path)

List

GET

/rest/{namePlural}

Update

PATCH

/rest/{namePlural}/{id}

id (path)

Delete

DELETE

/rest/{namePlural}/{id}

id (path)

Search

POST

/graphql

searchInput, nameSingular

Create Pipeline Record

Request Body

{
  "recordId": "uuid-of-parent-company-or-person",
  "stage": "SERIES_A",
  "fundingAmount": 5000000000000,
  "targetCloseDate": "2024-09-01T00:00:00.000Z"
}
{
  "recordId": "uuid-of-parent-company-or-person",
  "stage": "SERIES_A",
  "fundingAmount": 5000000000000,
  "targetCloseDate": "2024-09-01T00:00:00.000Z"
}
{
  "recordId": "uuid-of-parent-company-or-person",
  "stage": "SERIES_A",
  "fundingAmount": 5000000000000,
  "targetCloseDate": "2024-09-01T00:00:00.000Z"
}

Required Fields

  • recordId (UUID) — Parent record ID (Company or Person, depends on pipeline type)

Custom Properties

All other fields are pipeline-specific. Discover them via:

Field types follow the same rules as other entities:

  • SELECT fields: UPPER_SNAKE_CASE values

  • CURRENCY fields: amounts in micros

  • DATE_TIME fields: ISO 8601 format

  • BOOLEAN fields: true/false

Update Pipeline Record

Send only custom properties to update.

Get Pipeline Record

Default depth is 1 (includes parent record).

List Pipeline Records

GET /rest/{namePlural}?limit=60&order_by=createdAt[DescNullsLast]
GET /rest/{namePlural}?limit=60&order_by=createdAt[DescNullsLast]
GET /rest/{namePlural}?limit=60&order_by=createdAt[DescNullsLast]

Default depth is 1.

Delete Pipeline Record

Search Pattern

Pipeline search uses a DIFFERENT GraphQL query: searchPipeline (not search).

Step 1 — GraphQL:

{
  "query": "query SearchPipeline($searchInput: String!, $nameSingular: String!) { searchPipeline(searchInput: $searchInput, nameSingular: $nameSingular, limit: 5) { recordId } }",
  "variables": {
    "searchInput": "Acme",
    "nameSingular": "startupFundraising"
  }
}
{
  "query": "query SearchPipeline($searchInput: String!, $nameSingular: String!) { searchPipeline(searchInput: $searchInput, nameSingular: $nameSingular, limit: 5) { recordId } }",
  "variables": {
    "searchInput": "Acme",
    "nameSingular": "startupFundraising"
  }
}
{
  "query": "query SearchPipeline($searchInput: String!, $nameSingular: String!) { searchPipeline(searchInput: $searchInput, nameSingular: $nameSingular, limit: 5) { recordId } }",
  "variables": {
    "searchInput": "Acme",
    "nameSingular": "startupFundraising"
  }
}

POST to https://app.usedalil.ai/graphql

Step 2 — Fetch:

GET /rest/{namePlural}?filter=id[in]:[recordId1,recordId2]
GET /rest/{namePlural}?filter=id[in]:[recordId1,recordId2]
GET /rest/{namePlural}?filter=id[in]:[recordId1,recordId2]

Full Workflow




Filter Examples

# Records at a specific stage
filter=stage[eq]:FUNDED

# Records created after a date
filter=createdAt[gte]

# Records at a specific stage
filter=stage[eq]:FUNDED

# Records created after a date
filter=createdAt[gte]

# Records at a specific stage
filter=stage[eq]:FUNDED

# Records created after a date
filter=createdAt[gte]

Gotchas

  1. Endpoints are dynamic — The URL path comes from pipelineMetadata.namePlural. There is no fixed /rest/pipelines endpoint for records.

  2. Must discover pipelines first — Call GET /rest/metadata/pipelines before any pipeline operations.

  3. Uses different GraphQL query — Pipeline search uses searchPipeline, not search.

  4. GraphQL requires nameSingular — The search query needs the pipeline's singular name, not plural.

  5. Parent record is required on createrecordId links the pipeline record to a Company or Person.

  6. Default depth is 1 — Pipeline records default to depth 1 (includes parent record).

  7. Custom fields vary — Each pipeline has unique fields. Always check metadata before creating/updating.

  8. SELECT values are UPPER_SNAKE_CASE — Same as other entities: FUNDED, SERIES_A, DEMO, etc.

  9. Currency amounts in micros — Same rule: multiply by 1,000,000.

  10. GraphQL limit must be hardcoded, not a variable — Passing $limit: Int as a variable causes a type error. Inline it directly: limit: 5.

  11. GraphQL search returns IDs only — Follow up with GET /rest/{namePlural}?filter=id[in]:[id1,id2] to fetch full records.

  12. URL-encode GET filter params — Filter strings contain special characters ([, ], :) that break manually constructed URLs. Use URL encoding when making requests (e.g., curl -G --data-urlencode "filter=...").

On this page

Headings appear here in Preview.

On this page

Headings appear here in Preview.