---
title: "Get behavior signals over time"
method: POST
path: "/api/pulses/behaviors/timeseries/"
tags: ["Behaviors"]
---

# Get behavior signals over time

`POST /api/pulses/behaviors/timeseries/`

## Request

- Base URL: `https://api.respan.ai`
- URL: `https://api.respan.ai/api/pulses/behaviors/timeseries/`
- Auth: HTTP bearer

Returns how many spans fired each behavior per time bucket, or per polarity with `group_by: polarity`. `minute` buckets use exact range edges; larger buckets read the hourly rollup.

## Request body

- BehaviorTimeSeriesRequest
  - `start_time` string, date-time: Start of the range, ISO 8601. A time without an offset is read as UTC. Defaults to 7 days ago, which is also used if the value can't be parsed.
  - `end_time` string, date-time: End of the range, ISO 8601. A time without an offset is read as UTC. Defaults to now, which is also used if the value can't be parsed.
  - `environment` string: Only count spans from this environment, such as `prod` or `test`. Omit it to include every environment.
  - `granularity` 'minute' | 'hour' | 'day' | 'week': Bucket size.
  - `group_by` 'behavior' | 'polarity': `behavior` returns one series per behavior. `polarity` sums them into one series per polarity.
  - `behaviors` string[]: Only include these behavior keys (built-in names or custom behavior IDs). Omit for every behavior.

## Response `200`

Fired counts per bucket.

- BehaviorTimeSeries
  - `granularity` 'minute' | 'hour' | 'day' | 'week', required
  - `group_by` 'behavior' | 'polarity', required
  - `series` BehaviorTimeSeriesPoint[], required: Points ordered by `bucket`. A point appears only where the behavior fired, so empty buckets are missing.
    - `bucket` string, required: Start of the bucket. A date (`YYYY-MM-DD`) for `week` buckets. UTC, ISO 8601 without a timezone suffix.
    - `behavior` string: Behavior key: a built-in behavior's name (for example `refusal`) or a custom behavior's `id`. Present when `group_by` is `behavior`.
    - `polarity` 'negative' | 'positive' | 'neutral': Whether the behavior firing is good or bad: `negative` (an Issue), `positive` (a Win) or `neutral` (Info). Display metadata only; it does not change how spans are scored.
    - `fired_spans` integer, required: Spans where the behavior (or any behavior of the polarity) fired in the bucket.

## Other responses

- `400`: Invalid `granularity` or `group_by`.
- `403`: Forbidden: the API key is missing, invalid or expired; the key doesn't grant `logs:read` (Read access does); behaviors are turned off for the organization.
- `429`: Rate limited. This endpoint allows 60 requests per minute per organization.

## Changes

- **2026-10-21** `c30bcb383ee8`: 1 breaking, 7 info
  - the `series/items/polarity` response's property type changed from `string` to no type for status `200`
  - api operation id `behaviors_getBehaviorTimeSeries` removed and replaced with `getBehaviorTimeSeries`
  - api tag `Behaviors` added
  - api tag `behaviors` removed
  - …4 more
- **2026-10-02** `b830b79cfd52`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/respan/apis/respan-api/changes/api/pulses/behaviors/timeseries/post.md)

---

[API](https://skmtc.dev/respan/apis/respan-api.md) - [All operations](https://skmtc.dev/respan/apis/respan-api/llms.txt) - [OpenAPI document](https://skmtc.dev/respan/apis/respan-api/revisions/900841387635?raw)
