> ## Documentation Index
> Fetch the complete documentation index at: https://deepline.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Particle: Search Podcasts

> Search the podcast catalog by show name to find a podcast slug. Use this first. slugs are Particle handles and must not be guessed.

Search the podcast catalog by show name to find a podcast slug.

> [!NOTE]
>
> Tool ID: `particle_search_podcasts`

## Run this action

Use the TypeScript SDK for one call. Use `ctx.tools.execute(...)` inside a Play for durable calls, scheduled calls, or CSV processing.

```ts theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
import { Deepline } from 'deepline';

const deepline = await Deepline.connect();
const result = await deepline.tools.execute(
  'particle_search_podcasts',
  {
    "limit": 25,
    "cursor": "cursor_123",
    "q": "software companies hiring engineers"
  },
);

console.log(result.toolResponse.raw);
```

### CLI

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline tools execute particle_search_podcasts --input '{
  "limit": 25,
  "cursor": "cursor_123",
  "q": "software companies hiring engineers"
}' --json
```

## Example response

The SDK returns this shape at `result.toolResponse.raw`. The example values illustrate the response.

```json theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
{
  "data": {
    "data": [
      {
        "explicit": true,
        "id": "id_123",
        "title": "VP of Engineering"
      }
    ],
    "has_more": true
  }
}
```

Use `deepline describe particle_search_podcasts --json` for the latest machine-readable contract.

## Input reference

Searches the podcast catalog by show name — the canonical podcast search. Functionally equivalent to `GET /v1/podcasts?q=…`: the same forgiving, typo-tolerant ranked search, the same filters (topic, language, suitability tier, popularity, format), and the same `match_quality` signal on each result. To search *inside* episode dialogue, use `/v1/podcasts/episodes/search` instead.

| Name | Type | Required | Default | Details |
| - | - | - | - | - |
| `payload.limit` | `integer` | No | `25` | Results per page Format: `int64`. Minimum: 1. Maximum: 100. |
| `payload.cursor` | `string` | No | — | Opaque pagination cursor from previous response |
| `payload.q` | `string` | No | — | Search the catalog by podcast name. GET /v1/podcasts/search is the canonical search endpoint and accepts the same parameters. The search is forgiving: it handles typos, missing or extra words ('offline jon favreau' finds Offline with Jon Favreau), a name plus qualifiers ('equity techcrunch'), and pasted episode titles ('Ferrari \| Acquired' finds Acquired). The best matches come first, and each result's match\_quality tells you how confident the match is — including when a show matched only See the live schema for the complete constraint. |
| `payload.sort` | `"relevance" \| "popularity"` | No | — | Result ordering. relevance — the default whenever q is present — ranks by how well each podcast matches the query, breaking ties by popularity. popularity orders purely by the global popularity percentile (most popular first. podcasts not currently charting sort last), and also overrides topic\_id's concentration ordering. Without q or topic\_id, results are popularity-ordered either way. Allowed: `relevance`, `popularity`. |
| `payload.slug` | `string` | No | — | Filter by exact podcast slug (e.g., 'all-in'). Slugs are stable, human-readable identifiers returned on every podcast object. Maximum length: 200. |
| `payload.topic_id` | `string` | No | — | Filter by topic ID, ancestry slug (e.g., technology/artificial-intelligence), or ancestry path hash. Matches podcasts where the topic accounts for at least 20% of the show's episodes, ranked by topic concentration — not merely podcasts that mention it once. |
| `payload.language` | `string` | No | — | Filter by the podcast's language (ISO 639-1 code, e.g. 'en', 'fr'). Matches the primary language subtag, so 'fr' covers 'fr-FR'. |
| `payload.suitability_tier` | `"SAFE" \| "LIMITED" \| "SENSITIVE" \| "UNSAFE"` | No | — | Filter by brand-suitability tier (IAB Tech Lab Brand Safety & Suitability Framework, formerly GARM). Only returns podcasts whose most recent suitability analysis assigned this tier. Podcasts without a suitability analysis are excluded when this filter is set. Allowed: `SAFE`, `LIMITED`, `SENSITIVE`, `UNSAFE`. |
| `payload.popularity_threshold` | `number` | No | — | Restrict results to podcasts whose global popularity percentile is at least this value (accepted range \[0,1]). Omitting the parameter or passing 0 disables the filter. Only a value greater than 0 activates it. Popularity is always global — a cume\_dist ranking over all currently-charting podcasts (Apple Podcasts) — never scoped to topic\_id or any other filter. When the filter is active (threshold > 0), podcasts not currently charting have no percentile and are excluded, so a high threshold See the live schema for the complete constraint. |
| `payload.guest_frequency` | `array` | No | — | Filter by how often episodes feature a guest. Pass a comma-separated list to match any of several buckets — e.g. regular,always for interview-driven shows, or never for shows that don't host guests. Only matches podcasts with enough analyzed episodes to judge. values mirror the format.guest\_frequency field on podcast responses. Maximum items: 5. |
| `payload.format_signal` | `array` | No | — | Filter by detected production format. Pass a comma-separated list to match any of several formats — e.g. panel,call\_in. Values mirror the format.signals field on podcast responses. A show can carry several signals. Maximum items: 4. |
| `payload.has_ads` | `"true" \| "false"` | No | — | Filter by advertiser presence. Pass false to find ad-free shows — an assertion that requires the show to have enough analyzed episodes, so sparsely-analyzed podcasts are excluded rather than presumed ad-free. Allowed: `true`, `false`. |
| `payload.has_video` | `"true" \| "false"` | No | — | Filter by whether episodes have discovered video versions (e.g. YouTube releases). Allowed: `true`, `false`. |
| `payload.min_avg_episode_minutes` | `integer` | No | — | Only podcasts whose average episode runs at least this many minutes. Combine with max\_avg\_episode\_minutes to target a length band (e.g. 20–40 minute commute shows). Format: `int64`. Minimum: 0. Maximum: 10080. |
| `payload.max_avg_episode_minutes` | `integer` | No | — | Only podcasts whose average episode runs at most this many minutes. Format: `int64`. Minimum: 0. Maximum: 10080. |
| `payload.min_episodes_per_week` | `number` | No | — | Only podcasts publishing at least this many episodes per week on average (e.g. 5 for weekday dailies). Cadence is measured over the trailing 90 days. podcasts tracked too briefly to measure are excluded. Format: `double`. Minimum: 0. |
| `payload.max_episodes_per_week` | `number` | No | — | Only podcasts publishing at most this many episodes per week on average (e.g. 0.5 for fortnightly-or-slower shows). Format: `double`. Minimum: 0. |
| `payload.publishing_status` | `"active" \| "dormant"` | No | — | Filter by publishing activity: active shows have released an episode within the last 90 days. dormant shows have not. Allowed: `active`, `dormant`. |
| `payload.guest_occupation` | `string` | No | — | Only shows whose analyzed guests include someone listed under this SOC 2018 or ISCO-08 occupation (code, slug, or title), including a SOC group or everyday name such as physicians or doctors. A word with no occupation that names a field of research, such as oncologists, filters by the field. one that names a capacity, such as founders, is rejected. Maximum length: 200. |
| `payload.guest_field` | `string` | No | — | Only shows whose analyzed guests include someone listed under this ANZSRC 2020 field of research (code, slug, or title). Maximum length: 200. |
| `payload.min_analyzed_guest_appearances` | `integer` | No | — | Only shows with at least this many guest appearances analyzed for expertise. Raise it to steady the share filters below on shows with few analyzed guests. Format: `int64`. Minimum: 0. |
| `payload.min_established_guest_share` | `number` | No | — | Only shows where at least this share of analyzed guest appearances are by guests whose standing others conferred (0-1. 0 sets no bound). Format: `double`. Minimum: 0. Maximum: 1. |
| `payload.min_in_field_guest_share` | `number` | No | — | Only shows where at least this share of analyzed guest appearances stayed within the guest's field (0-1. 0 sets no bound). Format: `double`. Minimum: 0. Maximum: 1. |
| `payload.max_promotional_guest_share` | `number` | No | — | Only shows where at most this share of analyzed guest appearances were mainly promotional (0-1). 0 keeps only shows with none. Minimum: 0. Maximum: 1. |

<details>
  <summary>Show raw input schema</summary>

  ### Input JSON Schema

  ```json theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
  {
    "type": "object",
    "description": "Searches the podcast catalog by show name — the canonical podcast search. Functionally equivalent to `GET /v1/podcasts?q=…`: the same forgiving, typo-tolerant ranked search, the same filters (topic, language, suitability tier, popularity, format), and the same `match_quality` signal on each result. To search *inside* episode dialogue, use `/v1/podcasts/episodes/search` instead.",
    "properties": {
      "limit": {
        "type": "integer",
        "description": "Results per page",
        "default": 25,
        "minimum": 1,
        "maximum": 100,
        "format": "int64"
      },
      "cursor": {
        "type": "string",
        "description": "Opaque pagination cursor from previous response"
      },
      "q": {
        "type": "string",
        "description": "Search the catalog by podcast name. GET /v1/podcasts/search is the canonical search endpoint and accepts the same parameters. The search is forgiving: it handles typos, missing or extra words ('offline jon favreau' finds Offline with Jon Favreau), a name plus qualifiers ('equity techcrunch'), and pasted episode titles ('Ferrari | Acquired' finds Acquired). The best matches come first, and each result's match_quality tells you how confident the match is — including when a show matched only through its description (match_quality=description) rather than its name.",
        "maxLength": 200
      },
      "sort": {
        "type": "string",
        "description": "Result ordering. relevance — the default whenever q is present — ranks by how well each podcast matches the query, breaking ties by popularity. popularity orders purely by the global popularity percentile (most popular first; podcasts not currently charting sort last), and also overrides topic_id's concentration ordering. Without q or topic_id, results are popularity-ordered either way.",
        "enum": [
          "relevance",
          "popularity"
        ]
      },
      "slug": {
        "type": "string",
        "description": "Filter by exact podcast slug (e.g., 'all-in'). Slugs are stable, human-readable identifiers returned on every podcast object.",
        "maxLength": 200
      },
      "topic_id": {
        "type": "string",
        "description": "Filter by topic ID, ancestry slug (e.g., technology/artificial-intelligence), or ancestry path hash. Matches podcasts where the topic accounts for at least 20% of the show's episodes, ranked by topic concentration — not merely podcasts that mention it once."
      },
      "language": {
        "type": "string",
        "description": "Filter by the podcast's language (ISO 639-1 code, e.g. 'en', 'fr'). Matches the primary language subtag, so 'fr' covers 'fr-FR'."
      },
      "suitability_tier": {
        "type": "string",
        "description": "Filter by brand-suitability tier (IAB Tech Lab Brand Safety & Suitability Framework, formerly GARM). Only returns podcasts whose most recent suitability analysis assigned this tier. Podcasts without a suitability analysis are excluded when this filter is set.",
        "enum": [
          "SAFE",
          "LIMITED",
          "SENSITIVE",
          "UNSAFE"
        ]
      },
      "popularity_threshold": {
        "type": "number",
        "description": "Restrict results to podcasts whose global popularity percentile is at least this value (accepted range [0,1]). Omitting the parameter or passing 0 disables the filter; only a value greater than 0 activates it. Popularity is always global — a cume_dist ranking over all currently-charting podcasts (Apple Podcasts) — never scoped to topic_id or any other filter. When the filter is active (threshold > 0), podcasts not currently charting have no percentile and are excluded, so a high threshold combined with a narrow topic_id may return zero results; lower or remove the threshold to widen the set.",
        "minimum": 0,
        "maximum": 1,
        "format": "double"
      },
      "guest_frequency": {
        "type": [
          "array",
          "null"
        ],
        "description": "Filter by how often episodes feature a guest. Pass a comma-separated list to match any of several buckets — e.g. regular,always for interview-driven shows, or never for shows that don't host guests. Only matches podcasts with enough analyzed episodes to judge; values mirror the format.guest_frequency field on podcast responses.",
        "maxItems": 5,
        "items": {
          "type": "string",
          "enum": [
            "never",
            "rare",
            "occasional",
            "regular",
            "always"
          ]
        }
      },
      "format_signal": {
        "type": [
          "array",
          "null"
        ],
        "description": "Filter by detected production format. Pass a comma-separated list to match any of several formats — e.g. panel,call_in. Values mirror the format.signals field on podcast responses; a show can carry several signals.",
        "maxItems": 4,
        "items": {
          "type": "string",
          "enum": [
            "interview",
            "panel",
            "call_in",
            "solo_narrated"
          ]
        }
      },
      "has_ads": {
        "type": "string",
        "description": "Filter by advertiser presence. Pass false to find ad-free shows — an assertion that requires the show to have enough analyzed episodes, so sparsely-analyzed podcasts are excluded rather than presumed ad-free.",
        "enum": [
          "true",
          "false"
        ]
      },
      "has_video": {
        "type": "string",
        "description": "Filter by whether episodes have discovered video versions (e.g. YouTube releases).",
        "enum": [
          "true",
          "false"
        ]
      },
      "min_avg_episode_minutes": {
        "type": "integer",
        "description": "Only podcasts whose average episode runs at least this many minutes. Combine with max_avg_episode_minutes to target a length band (e.g. 20–40 minute commute shows).",
        "minimum": 0,
        "maximum": 10080,
        "format": "int64"
      },
      "max_avg_episode_minutes": {
        "type": "integer",
        "description": "Only podcasts whose average episode runs at most this many minutes.",
        "minimum": 0,
        "maximum": 10080,
        "format": "int64"
      },
      "min_episodes_per_week": {
        "type": "number",
        "description": "Only podcasts publishing at least this many episodes per week on average (e.g. 5 for weekday dailies). Cadence is measured over the trailing 90 days; podcasts tracked too briefly to measure are excluded.",
        "minimum": 0,
        "format": "double"
      },
      "max_episodes_per_week": {
        "type": "number",
        "description": "Only podcasts publishing at most this many episodes per week on average (e.g. 0.5 for fortnightly-or-slower shows).",
        "minimum": 0,
        "format": "double"
      },
      "publishing_status": {
        "type": "string",
        "description": "Filter by publishing activity: active shows have released an episode within the last 90 days; dormant shows have not.",
        "enum": [
          "active",
          "dormant"
        ]
      },
      "guest_occupation": {
        "type": "string",
        "description": "Only shows whose analyzed guests include someone listed under this SOC 2018 or ISCO-08 occupation (code, slug, or title), including a SOC group or everyday name such as physicians or doctors. A word with no occupation that names a field of research, such as oncologists, filters by the field; one that names a capacity, such as founders, is rejected.",
        "maxLength": 200
      },
      "guest_field": {
        "type": "string",
        "description": "Only shows whose analyzed guests include someone listed under this ANZSRC 2020 field of research (code, slug, or title).",
        "maxLength": 200
      },
      "min_analyzed_guest_appearances": {
        "type": "integer",
        "description": "Only shows with at least this many guest appearances analyzed for expertise. Raise it to steady the share filters below on shows with few analyzed guests.",
        "minimum": 0,
        "format": "int64"
      },
      "min_established_guest_share": {
        "type": "number",
        "description": "Only shows where at least this share of analyzed guest appearances are by guests whose standing others conferred (0-1; 0 sets no bound).",
        "minimum": 0,
        "maximum": 1,
        "format": "double"
      },
      "min_in_field_guest_share": {
        "type": "number",
        "description": "Only shows where at least this share of analyzed guest appearances stayed within the guest's field (0-1; 0 sets no bound).",
        "minimum": 0,
        "maximum": 1,
        "format": "double"
      },
      "max_promotional_guest_share": {
        "type": "number",
        "description": "Only shows where at most this share of analyzed guest appearances were mainly promotional (0-1); 0 keeps only shows with none.",
        "minimum": 0,
        "maximum": 1
      }
    },
    "required": [],
    "additionalProperties": false
  }
  ```
</details>

## Output reference

Standard tool result payload.

| Name | Type | Required | Default | Details |
| - | - | - | - | - |
| `result.data` | `object` | Yes | — | Provider response payload. |
| `result.data.cursor` | `string` | No | — | Pass to next request for more results |
| `result.data.data` | `array` | Yes | — | List of results |
| `result.data.data[].bias` | `string` | No | — | Political bias rating for the podcast: EXTREME\_LEFT, LEANS\_LEFT, LEFT, CENTER, RIGHT, LEANS\_RIGHT, or EXTREME\_RIGHT. Empty when the podcast is not substantively political or has not been evaluated yet. Fetch GET /v1/podcasts/\{id}/bias for the full analysis including reasoning and evidence. |
| `result.data.data[].coverage` | `object` | No | — | — |
| `result.data.data[].coverage.back_catalogue` | `object` | No | — | — |
| `result.data.data[].coverage.back_catalogue.complete` | `boolean` | Yes | — | true when the discovery sources listed the podcast's whole history. false when PodcastIndex capped its listing at 1,000 episodes, so older episodes may exist that neither it nor the podcast's own feed lists. |
| `result.data.data[].coverage.back_catalogue.feed_item_count` | `integer` | No | — | Items the podcast's own feed listed. Absent when the feed could not be read. Format: `int64`. |
| `result.data.data[].coverage.back_catalogue.imported_at` | `string` | Yes | — | When the back catalogue was last imported. Format: `date-time`. |
| `result.data.data[].coverage.back_catalogue.podcastindex_episode_count` | `integer` | Yes | — | Episodes PodcastIndex listed, at most 1,000. Format: `int64`. |
| `result.data.data[].coverage.counted_at` | `string` | No | — | When these counts were computed. They refresh hourly, so an episode ingested, transcribed or requested since is not reflected yet. Each episode's own transcript\_status is always current. Format: `date-time`. |
| `result.data.data[].coverage.discovered_episode_count` | `integer` | Yes | — | Every episode we know of, transcribed or not: the episodes we have ingested plus the podcast's back catalogue. The transcript\_statuses counts sum to it. Format: `int64`. |
| `result.data.data[].coverage.newest_episode_published_at` | `string` | No | — | Publication date of the newest discovered episode. Format: `date-time`. |
| `result.data.data[].coverage.oldest_episode_published_at` | `string` | No | — | Publication date of the oldest discovered episode. Format: `date-time`. |
| `result.data.data[].coverage.transcript_statuses` | `array \| null` | Yes | — | Discovered episodes by transcript\_status, one entry per status. Unlike episode\_count on the podcast, which counts ingested episodes, these include the back catalogue. |
| `result.data.data[].coverage.transcript_statuses[].count` | `integer` | Yes | — | Discovered episodes with this status. Format: `int64`. |
| `result.data.data[].coverage.transcript_statuses[].transcript_status` | `"transcribed" \| "processing" \| "queued" \| "requestable" \| "unavailable"` | Yes | — | The status counted. See Episode.transcript\_status. Allowed: `transcribed`, `processing`, `queued`, `requestable`, `unavailable`. |
| `result.data.data[].coverage.years` | `array \| null` | Yes | — | Discovered and transcribed episodes per publication year, newest year first. Episodes without a publication date are counted in the totals only. |
| `result.data.data[].coverage.years[].discovered` | `integer` | Yes | — | Episodes published that year that we know of. Format: `int64`. |
| `result.data.data[].coverage.years[].transcribed` | `integer` | Yes | — | Of those, episodes with a transcript. Format: `int64`. |
| `result.data.data[].coverage.years[].year` | `integer` | Yes | — | Publication year (UTC). Format: `int64`. |
| `result.data.data[].description` | `string` | No | — | Podcast description |
| `result.data.data[].episode_count` | `integer` | No | — | Total number of episodes Format: `int64`. |
| `result.data.data[].explicit` | `boolean` | Yes | — | Whether the podcast contains explicit content |
| `result.data.data[].format` | `object` | No | — | — |
| `result.data.data[].format.avg_episode_minutes` | `integer` | No | — | Average episode length in minutes. Omitted when no episode durations are known. Format: `int64`. |
| `result.data.data[].format.episodes_per_week` | `number` | No | — | Publishing cadence over the trailing 90 days, in episodes per week (e.g. 5.0 for a weekday daily, 0.5 for a fortnightly show). Omitted until the show has been tracked long enough to measure reliably. Format: `double`. |
| `result.data.data[].format.guest_frequency` | `string` | No | — | How often episodes feature a guest: never, rare, occasional, regular, or always. Derived from the share of analyzed episodes with at least one guest speaker. Omitted when too few episodes have been analyzed to judge. Filter the catalog with the guest\_frequency query parameter on GET /v1/podcasts. |
| `result.data.data[].format.has_ads` | `boolean` | No | — | Whether episodes carry advertiser reads. Omitted when too few episodes have been analyzed to judge. The full advertising profile (sponsors, read types, ad load) is served by GET /v1/podcasts/\{id}/advertising. |
| `result.data.data[].format.has_video` | `boolean` | Yes | — | Whether any episode has a discovered video version (e.g. a YouTube release). |
| `result.data.data[].format.publishing_status` | `string` | No | — | Whether the show is still releasing episodes: active (published within the last 90 days) or dormant. Omitted when no publish dates are known. |
| `result.data.data[].format.signals` | `array \| null` | No | — | Production formats detected from the show's speaker-role mix: interview, panel, call\_in, and/or solo\_narrated. A show can carry several (a panel show with call-in segments). Omitted when too few episodes have been analyzed to judge. |
| `result.data.data[].id` | `string` | Yes | — | Unique identifier |
| `result.data.data[].image_url` | `string` | No | — | Cover image URL |
| `result.data.data[].language` | `string` | No | — | ISO 639-1 language code |
| `result.data.data[].match_quality` | `"exact" \| "partial" \| "fuzzy" \| "description" \| "speculative"` | No | — | How confidently this result matches your q search, strongest first. exact: this is the show with that name. partial: the name matches your search strongly (your search may have included extra words). fuzzy: the name is similar but not the same — it may be the show you meant with a typo, or a different show with a near-identical name. verify before relying on it. description: your search text appears in the show's description rather than its name. speculative: a loose suggestion, listed last. See the live schema for the complete constraint. |
| `result.data.data[].political_context` | `string` | No | — | Political framework the bias rating is calibrated against: US, UK, EU, CANADA, AUSTRALIA, INDIA, OTHER. Omitted when the latest analysis returned NOT\_POLITICAL or when no analysis has been run yet. |
| `result.data.data[].popularity` | `number` | No | — | Global popularity percentile in (0,1], a cume\_dist ranking over all currently-charting podcasts (Apple Podcasts charts). Higher is more popular. The most popular podcast is 1.0. Always global — never scoped to a topic\_id or other filter. Omitted when the podcast is not currently charting. Pair with the popularity\_threshold query parameter on GET /v1/podcasts to filter the catalog by this value. Format: `double`. |
| `result.data.data[].publisher` | `object` | No | — | — |
| `result.data.data[].publisher.id` | `string` | Yes | — | Publisher ID |
| `result.data.data[].publisher.name` | `string` | Yes | — | Publisher name |
| `result.data.data[].publisher.slug` | `string` | No | — | Human-readable slug identifier (e.g., 'goalhanger', 'iheartpodcasts'). When present, accepted in place of the ID anywhere a publisher reference is taken in the API. Occasionally absent on publishers whose name doesn't slugify (e.g., scripts not representable in ASCII URL slugs). |
| `result.data.data[].recommended_guests` | `array \| null` | No | — | The five guests the show could plausibly book next (lean form, no via). Present only on GET /v1/podcasts/\{id} with include=recommended\_guests. The paged list is GET /v1/podcasts/\{id}/recommendations/guests. |
| `result.data.data[].recommended_guests[].band` | `"strong" \| "moderate" \| "weak"` | Yes | — | Coarse class of the score. Allowed: `strong`, `moderate`, `weak`. |
| `result.data.data[].recommended_guests[].person` | `object` | Yes | — | — |
| `result.data.data[].recommended_guests[].person.description` | `string` | No | — | Short description (e.g. current role), when known. |
| `result.data.data[].recommended_guests[].person.id` | `string` | Yes | — | Encoded Person identifier |
| `result.data.data[].recommended_guests[].person.image_url` | `string` | No | — | Canonical headshot URL when one is known for the Person |
| `result.data.data[].recommended_guests[].person.name` | `string` | Yes | — | Display name |
| `result.data.data[].recommended_guests[].person.slug` | `string` | No | — | Stable human-readable handle (e.g. 'satya-nadella'). Recommended canonical identifier on every Particle Pro person surface. |

The table shows the first 50 fields. Use the live contract below for every field.

> [!NOTE]
>
> This output schema is too large for an inline display. Read the complete live contract with `deepline describe particle_search_podcasts --json`.

## Deepline cost

* Pricing model: `fixed` (per call).
* Estimated Deepline credits: `0` per pricing unit.
* Provider-native pricing may still exist outside Deepline credit billing.

## Related documentation

* [Particle provider guide](https://deepline.com/docs/providers/particle/guide.md)
* [SDK V2 quickstart](https://deepline.com/docs/sdk-v2/quickstart.md)
* [SDK reference](https://deepline.com/docs/sdk-v2/sdk-reference.md)
* [Run tools across a CSV](https://deepline.com/docs/sdk-v2/batch-csv.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.