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

# GET /v1/survey_cycles — List the Cycles of a Recurring Survey

> List the open and closed cycles of a recurring survey, with their exact start and end dates, to compare engagement scores across periods. Planned for Export API v1.4.0.

<Warning>
  Planned for Export API v1.4.0 — not yet available on `api.honestly.com`. Documented here so you can plan your integration. Watch [Versioning](/developers/concepts/versioning) for the release.
</Warning>

A recurring survey runs in **cycles** — each cycle opens, collects responses, and closes. This endpoint lists those cycles with their exact boundaries, so you can align an export to the periods your survey actually ran in rather than to arbitrary calendar dates.

This is what makes a like-for-like period comparison possible: pass one cycle's boundaries to [`/v1/scores`](/developers/api-reference/scores), then the previous cycle's.

## Endpoint

```
GET https://api.honestly.com/v1/survey_cycles
```

## Query Parameters

<ParamField query="survey_id" type="integer">
  Return only cycles of this survey. Survey IDs come from [`/v1/surveys`](/developers/api-reference/surveys). Omit to list cycles of every survey in the account.
</ParamField>

<ParamField query="limit" type="integer">
  Maximum number of cycles to return per page. Accepts values from `0` to `1000`. Defaults to `100`.
</ParamField>

<ParamField query="offset" type="integer">
  Number of cycles to skip before returning results. Defaults to `0`.
</ParamField>

## Example Request

```bash theme={null}
curl -G "https://api.honestly.com/v1/survey_cycles" \
  -H "X-Api-Key: YOUR_SECRET_API_KEY" \
  --data-urlencode "survey_id=17"
```

## Example Response

```json theme={null}
{
  "total_count": 4,
  "cycles": [
    {
      "id": "9f1c8a52-2b7d-4f3e-9d21-0c5a7e4b1f88",
      "survey_id": 17,
      "opened_at": "2026-04-01T06:00:00Z",
      "closed_at": null,
      "timezone": "Europe/Berlin"
    },
    {
      "id": "7b3a1e04-6c92-4a1b-8f75-3d2e9a6c04b1",
      "survey_id": 17,
      "opened_at": "2026-01-01T06:00:00Z",
      "closed_at": "2026-01-14T21:59:59Z",
      "timezone": "Europe/Berlin"
    }
  ]
}
```

## Response Fields

<ResponseField name="total_count" type="integer">
  Total number of cycles matching the filter, for pagination.
</ResponseField>

<ResponseField name="cycles" type="array">
  <Expandable title="cycle">
    <ResponseField name="id" type="string">
      Cycle UUID. Pass it as `survey_cycle_ids` to [`/v1/text_responses`](/developers/api-reference/text-responses) to export one cycle's free-text answers. It also identifies the cycle in the [participation breakdown](/developers/api-reference/scores#participation-rate) returned by `/v1/scores`.
    </ResponseField>

    <ResponseField name="survey_id" type="integer">
      ID of the survey this cycle belongs to, matching [`/v1/surveys`](/developers/api-reference/surveys).
    </ResponseField>

    <ResponseField name="opened_at" type="string">
      RFC 3339 datetime in UTC when the cycle opened.
    </ResponseField>

    <ResponseField name="closed_at" type="string | null">
      RFC 3339 datetime in UTC when the cycle closed. `null` means the cycle is still open.
    </ResponseField>

    <ResponseField name="timezone" type="string">
      The survey's configured timezone, for rendering local dates. Timestamps themselves are always UTC.
    </ResponseField>
  </Expandable>
</ResponseField>

Cycles are returned newest first.

## Comparing a score to the previous period

Read the cycles, then call [`/v1/scores`](/developers/api-reference/scores) once per cycle using its boundaries:

```bash theme={null}
# current cycle
curl -G "https://api.honestly.com/v1/scores" \
  -H "X-Api-Key: YOUR_SECRET_API_KEY" \
  --data-urlencode "question_ids=121" \
  --data-urlencode "survey_ids=17" \
  --data-urlencode "period_from=2026-04-01T06:00:00Z" \
  --data-urlencode "period_to=2026-04-14T21:59:59Z"

# previous cycle
curl -G "https://api.honestly.com/v1/scores" \
  -H "X-Api-Key: YOUR_SECRET_API_KEY" \
  --data-urlencode "question_ids=121" \
  --data-urlencode "survey_ids=17" \
  --data-urlencode "period_from=2026-01-01T06:00:00Z" \
  --data-urlencode "period_to=2026-01-14T21:59:59Z"
```

<Note>
  There is no built-in comparison endpoint, because "previous period" means different things in different reports — the previous cycle, the same quarter a year earlier, a fixed baseline. Two calls cost one extra round trip and let you compare anything to anything.

  Each call is anonymity-checked independently, so a comparison can legitimately return a number for one period and a suppressed value for the other.
</Note>
