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

# Export subscriptions CSV

> Generate a GZip-compressed CSV export of your current subscription data using this API endpoint.

## Overview

Use this endpoint to request a GZip-compressed CSV export of all your [Subscriptions data](/docs/en/subscriptions) from OneSignal. The export includes both default and optional user data fields, and supports filters to refine the dataset. The file is downloadable via a URL returned in the API response.

***

## How to use this API

By default, this will export all Subscriptions within the app.

**Optional filters:**

You can narrow the export using:

* `segment_name`: Only export Subscriptions from a specific segment. Segment membership rules determine which subscription statuses are included. Use with `include_unsubscribed` to include unsubscribed subscriptions.
* `last_active_since`: Export Subscriptions where their `last_session` was after a specific Unix timestamp. Example: Use `1704067200` for Subscriptions active since January 1st, 2024.
* `include_unsubscribed`: When exporting a segment, set to `true` to include unsubscribed subscriptions alongside subscribed ones. By default, segment-filtered exports only return subscribed subscriptions. This parameter has no effect when `segment_name` is not provided.

**Example successful response:**

```json 200 OK theme={null}
{
  "csv_file_url": "https://onesignal.com/csv_exports/b2f7f966.../users_1849..._2024-11-10.csv.gz"
}
```

**Export time considerations:**

* Generation speed: \~2,000 records per second.
* File readiness: The `csv_file_url` may return a 404 until generation completes.
* Download retry: Poll the file URL at intervals until the file is ready.
* File expiration: The file remains available for 3 days after generation.
* Concurrency: Only one export per OneSignal account can run at a time.

**File not ready (404 response)**

```xml 404 CSV GET  theme={null}
This XML file does not appear to have any style information
associated with it. The document tree is shown below.
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
</Error>
```

<Info>
  You can safely poll the `csv_file_url` until the file becomes available. Implement retry logic based on expected data volume and generation speed.

  Only one export is allowed at a time per account. Wait until the `.csv.gz` file is downloaded before triggering another export.
</Info>

***

## CSV data contents

The export includes two types of fields:

* **Default fields**: Always included unless excluded by schema changes.
* **Extra fields**: Must be explicitly requested using the `extra_fields` parameter.

### Default fields

* `id`: The Subscription ID.

* `identifier`: The push token, email address, or phone number depending on the Subscription type.

* `session_count`: The number of times the user has opened the app.

* `language`: The user's language in ISO 639-1 format.

* `timezone`: Deprecated — use `timezone_id` instead.

* `game_version`: The version of your app that the user is currently using.

* `device_os`: The device's operating system version.

* `device_type`: Integer representing channel/device type.
  * `0`: iOSPush
  * `1`: AndroidPush
  * `2`: FireOSPush
  * `5`: ChromePush
  * `7,17`: SafariPush
  * `11`: Email
  * `14`: SMS

* `device_model`: The device's hardware string.

* `ad_id`: Deprecated.

* `tags`: Custom key/value data.

* `last_active`: The last time the user was active.

* `playtime`: The total amount of time in seconds the user had the mobile app open.

* `created_at`: The first time the user was seen.

* `invalid_identifier`: Boolean flag for unsubscribed state.
  * `t`: Unsubscribed
  * `f`: Subscribed

### Extra fields (`extra_fields`)

Pass `extra_fields` in your request to include any of the following:

* `external_user_id`: Maps to the `external_id` of the user.

* `onesignal_id`: OneSignal's user ID.

* `location`: Adds the `lat` and `long` coordinates if set.

* `country`: The user's country in ISO 3166-1 Alpha 2 format.

* `ip`: The IP address if detected. Can be IPv4 or IPv6 format.

* `web_auth`: Only available to OneSignal SDKs. The `web_auth` key for web push.

* `web_p256`: Only available to OneSignal SDKs. The `web_p256` for web push.

* `unsubscribed_at`: The date and time the user last unsubscribed. They may resubscribe at any time. Check the `invalid_identifier` field to determine if they are currently subscribed.

* `notification_types`: Indicates the reason for the subscription status. Values are updated automatically as events are detected by our frontend SDKs but you should set this manually when updating via our REST API. `1` is subscribed and `-31` is reserved for unsubscribed via the API. See [Subscriptions](/docs/en/subscriptions#notification-types).

* `timezone_id`: The user's timezone in IANA format.

***


## OpenAPI

````yaml POST /players/csv_export
openapi: 3.1.0
info:
  title: api.onesignal.com
  version: '11.6'
servers:
  - url: https://api.onesignal.com
security:
  - {}
paths:
  /players/csv_export:
    post:
      summary: Export subscriptions CSV
      description: >-
        Generate a GZip-compressed CSV export of your current subscription data
        using this API endpoint.
      operationId: csv-export
      parameters:
        - name: app_id
          in: query
          description: >-
            Your OneSignal App ID in UUID v4 format. See [Keys &
            IDs](/docs/en/keys-and-ids).
          required: true
          schema:
            type: string
            default: YOUR_APP_ID
        - name: Authorization
          in: header
          description: >-
            Your App API key with prefix `Key `. See [Keys &
            IDs](/docs/en/keys-and-ids).
          required: true
          schema:
            type: string
            default: Key YOUR_APP_API_KEY
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                extra_fields:
                  type: array
                  description: Additional properties that you can include in the CSV.
                  default:
                    - external_user_id
                    - country
                    - timezone_id
                  items:
                    type: string
                    enum:
                      - external_user_id
                      - onesignal_id
                      - location
                      - country
                      - rooted
                      - ip
                      - web_auth
                      - web_p256
                      - unsubscribed_at
                      - notification_types
                      - timezone_id
                last_active_since:
                  type: string
                  description: >-
                    A Unix timestamp (in seconds) used to filter Subscriptions
                    based on recent activity. Only Subscriptions with a
                    `last_session` timestamp after this value will be included
                    in the export. Example: To export Subscriptions active since
                    January 1st, 2024, use `1704067200`.
                segment_name:
                  type: string
                  description: >-
                    The name of a specific segment to filter the export. Only
                    subscriptions that belong to this segment will be included
                    in the CSV. Omit this field to export all subscriptions in
                    the app.
                include_unsubscribed:
                  type: boolean
                  description: >-
                    When used with `segment_name`, set to `true` to include
                    unsubscribed subscriptions in the export. By default,
                    segment-filtered exports only return subscribed
                    subscriptions. This parameter has no effect when
                    `segment_name` is not provided.
                  default: false
      responses:
        '200':
          description: '200'
          content:
            application/json:
              schema:
                type: object
                properties:
                  csv_file_url:
                    type: string
                    description: >-
                      The URL to download the CSV file. The file is available
                      for 3 days after generation.
        '400':
          description: '400'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorResponse'
              example:
                errors:
                  - 'Request is malformed: Failed to parse app_id from request'
        '429':
          description: >-
            Rate limit exceeded. Wait the number of seconds in the `Retry-After`
            header before retrying.
          headers:
            Retry-After:
              description: >-
                Number of seconds to wait before retrying the request. Always
                emitted on 429 responses.
              schema:
                type: integer
                minimum: 0
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorResponse'
              example:
                errors:
                  - API rate limit exceeded
        '503':
          description: >-
            Service temporarily unavailable. Retry after a short backoff. The
            body may be empty or non-JSON in some failure modes.
          headers:
            Retry-After:
              description: >-
                Number of seconds to wait before retrying. Optional — may be
                absent when the response is generated upstream.
              schema:
                type: integer
                minimum: 0
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorResponse'
              example:
                errors:
                  - Service temporarily unavailable
      deprecated: false
      security: []
      x-codeSamples:
        - lang: typescript
          label: Node.js SDK
          source: >-
            import Onesignal from '@onesignal/node-onesignal';


            const configuration = Onesignal.createConfiguration({
                restApiKey: '<YOUR_REST_API_KEY>',
            });

            const apiInstance = new Onesignal.DefaultApi(configuration);


            // string | The app ID that you want to export devices from

            const appId: string = "00000000-0000-0000-0000-000000000000";

            // ExportSubscriptionsRequestBody (optional)

            const exportSubscriptionsRequestBody:
            Onesignal.ExportSubscriptionsRequestBody = {
                extra_fields: [
                  "extra_fields_example",
                ],
                last_active_since: "last_active_since_example",
                segment_name: "segment_name_example",
              };

            try {
              const response = await apiInstance.exportSubscriptions(appId, exportSubscriptionsRequestBody);
              console.log(response);
            } catch (e) {
              if (e instanceof Onesignal.ApiException) {
                // `e.errorMessages` flattens any error-envelope shape to a `string[]`;
                // the raw parsed body remains on `e.body`.
                console.error("exportSubscriptions failed: HTTP " + e.code, e.errorMessages);
              } else {
                throw e;
              }
            }
        - lang: python
          label: Python SDK
          source: >-
            import onesignal

            from onesignal.api import default_api

            from onesignal.models import *

            from pprint import pprint


            # See configuration.py for a list of all supported configuration
            parameters.

            # Some of the OneSignal endpoints require ORGANIZATION_API_KEY token
            for authorization, while others require REST_API_KEY.

            # We recommend adding both of them in the configuration page so that
            you will not need to figure it out yourself.

            configuration = onesignal.Configuration(
                rest_api_key = "YOUR_REST_API_KEY", # App REST API key required for most endpoints
                organization_api_key = "YOUR_ORGANIZATION_KEY" # Organization key is only required for creating new apps and other top-level endpoints
            )



            # Enter a context with an instance of the API client

            with onesignal.ApiClient(configuration) as api_client:
                # Create an instance of the API class
                api_instance = default_api.DefaultApi(api_client)
                app_id = "00000000-0000-0000-0000-000000000000" # The app ID that you want to export devices from 
                export_subscriptions_request_body = ExportSubscriptionsRequestBody(
                    extra_fields=[
                        "extra_fields_example",
                    ],
                    last_active_since="last_active_since_example",
                    segment_name="segment_name_example",
                ) 

                # example passing only required values which don't have defaults set
                try:
                    # Export CSV of Subscriptions
                    api_response = api_instance.export_subscriptions(app_id)
                    pprint(api_response)
                except onesignal.ApiException as e:
                    print("Exception when calling DefaultApi->export_subscriptions: %s\n" % e)
                    print("Status Code: %s" % e.status)
                    print("Response Body: %s" % e.body)

                # example passing only required values which don't have defaults set
                # and optional values
                try:
                    # Export CSV of Subscriptions
                    api_response = api_instance.export_subscriptions(app_id, export_subscriptions_request_body=export_subscriptions_request_body)
                    pprint(api_response)
                except onesignal.ApiException as e:
                    print("Exception when calling DefaultApi->export_subscriptions: %s\n" % e)
                    print("Status Code: %s" % e.status)
                    print("Response Body: %s" % e.body)
        - lang: php
          label: PHP SDK
          source: >-
            <?php

            require_once(__DIR__ . '/vendor/autoload.php');



            // Configure Bearer authorization: rest_api_key

            $config = onesignal\client\Configuration::getDefaultConfiguration()
                                                            ->setRestApiKeyToken('YOUR_REST_API_KEY')
                                                            ->setOrganizationApiKeyToken('YOUR_ORGANIZATION_API_KEY');



            $apiInstance = new onesignal\client\Api\DefaultApi(
                // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
                // This is optional, `GuzzleHttp\Client` will be used as default.
                new GuzzleHttp\Client(),
                $config
            );

            $app_id = '00000000-0000-0000-0000-000000000000'; // string | The
            app ID that you want to export devices from

            $export_subscriptions_request_body = new
            \onesignal\client\model\ExportSubscriptionsRequestBody(); //
            \onesignal\client\model\ExportSubscriptionsRequestBody


            try {
                $result = $apiInstance->exportSubscriptions($app_id, $export_subscriptions_request_body);
                print_r($result);
            } catch (\onesignal\client\ApiException $e) {
                echo 'Exception when calling DefaultApi->exportSubscriptions: ', $e->getMessage(), PHP_EOL;
                echo 'Status Code: ', $e->getCode(), PHP_EOL;
                // getErrorMessages() flattens any error-envelope shape to a string[];
                // the raw body remains on getResponseBody().
                echo 'Error Messages: ', implode(', ', $e->getErrorMessages()), PHP_EOL;
                echo 'Response Body: ', $e->getResponseBody(), PHP_EOL;
            } catch (\Exception $e) {
                echo 'Exception when calling DefaultApi->exportSubscriptions: ', $e->getMessage(), PHP_EOL;
            }
        - lang: go
          label: Go SDK
          source: |-
            package main

            import (
                "context"
                "fmt"
                "os"

                "github.com/OneSignal/onesignal-go-api/v5"
            )

            func main() {
                appId := "00000000-0000-0000-0000-000000000000" // string | The app ID that you want to export devices from
                exportSubscriptionsRequestBody := *onesignal.NewExportSubscriptionsRequestBody() // ExportSubscriptionsRequestBody |  (optional)

                configuration := onesignal.NewConfiguration()
                apiClient := onesignal.NewAPIClient(configuration)

                restAuth := context.WithValue(context.Background(), onesignal.RestApiKey, "YOUR_REST_API_KEY") // App REST API key required for most endpoints

                resp, r, err := apiClient.DefaultApi.ExportSubscriptions(restAuth, appId).ExportSubscriptionsRequestBody(exportSubscriptionsRequestBody).Execute()

                if err != nil {
                    fmt.Fprintf(os.Stderr, "Error when calling `DefaultApi.ExportSubscriptions``: %v\n", err)
                    fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
                    if apiErr, ok := err.(*onesignal.GenericOpenAPIError); ok {
                        // ErrorMessages() flattens any error-envelope shape to a []string;
                        // the raw body remains on Body().
                        fmt.Fprintf(os.Stderr, "Error Messages: %v\n", apiErr.ErrorMessages())
                        fmt.Fprintf(os.Stderr, "Response Body: %s\n", apiErr.Body())
                    }
                }
                // response from `ExportSubscriptions`: ExportSubscriptionsSuccessResponse
                fmt.Fprintf(os.Stdout, "Response from `DefaultApi.ExportSubscriptions`: %v\n", resp)
            }
        - lang: ruby
          label: Ruby SDK
          source: >-
            require 'onesignal'

            # setup authorization

            OneSignal.configure do |config|
              # Configure Bearer authorization: rest_api_key
              config.rest_api_key = 'YOUR_BEARER_TOKEN'

            end


            api_instance = OneSignal::DefaultApi.new

            app_id = '00000000-0000-0000-0000-000000000000' # String | The app
            ID that you want to export devices from

            opts = {
              export_subscriptions_request_body: OneSignal::ExportSubscriptionsRequestBody.new # ExportSubscriptionsRequestBody | 
            }


            begin
              # Export CSV of Subscriptions
              result = api_instance.export_subscriptions(app_id, opts)
              p result
            rescue OneSignal::ApiError => e
              puts "Error when calling DefaultApi->export_subscriptions: #{e}"
              puts "Status Code: #{e.code}"
              # `e.error_messages` flattens any error-envelope shape to an Array<String>;
              # the raw body remains on `e.response_body`.
              puts "Error Messages: #{e.error_messages}"
              puts "Response Body: #{e.response_body}"
            end
        - lang: java
          label: Java SDK
          source: |-
            // Import classes:
            import com.onesignal.client.ApiClient;
            import com.onesignal.client.ApiException;
            import com.onesignal.client.Configuration;
            import com.onesignal.client.auth.*;
            import com.onesignal.client.model.*;
            import com.onesignal.client.api.DefaultApi;

            public class Example {
              public static void main(String[] args) {
                ApiClient defaultClient = Configuration.getDefaultApiClient();
                defaultClient.setBasePath("https://api.onesignal.com");
                
                // Configure HTTP bearer authorization: rest_api_key
                HttpBearerAuth rest_api_key = (HttpBearerAuth) defaultClient.getAuthentication("rest_api_key");
                rest_api_key.setBearerToken("BEARER TOKEN");

                DefaultApi apiInstance = new DefaultApi(defaultClient);
                String appId = "00000000-0000-0000-0000-000000000000"; // String | The app ID that you want to export devices from
                ExportSubscriptionsRequestBody exportSubscriptionsRequestBody = new ExportSubscriptionsRequestBody(); // ExportSubscriptionsRequestBody | 
                try {
                  ExportSubscriptionsSuccessResponse result = apiInstance.exportSubscriptions(appId, exportSubscriptionsRequestBody);
                  System.out.println(result);
                } catch (ApiException e) {
                  System.err.println("Exception when calling DefaultApi#exportSubscriptions");
                  System.err.println("Status code: " + e.getCode());
                  // getErrorMessages() flattens any error-envelope shape to a List<String>;
                  // the raw body remains on getResponseBody().
                  System.err.println("Error messages: " + e.getErrorMessages());
                  System.err.println("Reason: " + e.getResponseBody());
                  System.err.println("Response headers: " + e.getResponseHeaders());
                  e.printStackTrace();
                }
              }
            }
        - lang: csharp
          label: C# SDK
          source: |-
            using System;
            using System.Collections.Generic;
            using System.Diagnostics;
            using OneSignalApi.Api;
            using OneSignalApi.Client;
            using OneSignalApi.Model;

            namespace Example
            {
                public class ExportSubscriptionsExample
                {
                    public static void Main()
                    {
                        Configuration config = new Configuration();
                        config.BasePath = "https://api.onesignal.com";
                        // Configure Bearer token for authorization: rest_api_key
                        config.AccessToken = "YOUR_BEARER_TOKEN";

                        var apiInstance = new DefaultApi(config);
                        var appId = "00000000-0000-0000-0000-000000000000";  // string | The app ID that you want to export devices from
                        var exportSubscriptionsRequestBody = new ExportSubscriptionsRequestBody(); // ExportSubscriptionsRequestBody |  (optional) 

                        try
                        {
                            // Export CSV of Subscriptions
                            ExportSubscriptionsSuccessResponse result = apiInstance.ExportSubscriptions(appId, exportSubscriptionsRequestBody);
                            Debug.WriteLine(result);
                        }
                        catch (ApiException  e)
                        {
                            Debug.Print("Exception when calling DefaultApi.ExportSubscriptions: " + e.Message );
                            Debug.Print("Status Code: "+ e.ErrorCode);
                            // e.ErrorMessages flattens any error-envelope shape to an IReadOnlyList<string>;
                            // the raw body remains on e.ErrorContent.
                            Debug.Print("Error Messages: " + string.Join(", ", e.ErrorMessages));
                            Debug.Print("Response Body: " + e.ErrorContent);
                            Debug.Print(e.StackTrace);
                        }
                    }
                }
            }
        - lang: rust
          label: Rust SDK
          source: |-
            use onesignal_rust_api::apis::configuration::Configuration;
            use onesignal_rust_api::apis::default_api;

            use onesignal_rust_api::models;


            #[tokio::main]
            async fn main() {
                let mut configuration = Configuration::new();
                configuration.rest_api_key_token = Some("YOUR_REST_API_KEY".to_string());


                // Realistic values are pulled from the spec's `example:` fields where present.
                let app_id: &str = "00000000-0000-0000-0000-000000000000";
                let export_subscriptions_request_body: Option<models::ExportSubscriptionsRequestBody> = None;

                match default_api::export_subscriptions(&configuration, app_id, export_subscriptions_request_body).await {
                    Ok(resp) => println!("{:?}", resp),
                    Err(e @ onesignal_rust_api::apis::Error::ResponseError(_)) => {
                        // `e.error_messages()` flattens any error-envelope shape to a Vec<String>;
                        // the raw response remains on the ResponseError variant.
                        eprintln!("export_subscriptions failed: {:?}", e.error_messages());
                    }
                    Err(e) => eprintln!("export_subscriptions failed: {:?}", e),
                }
            }
components:
  schemas:
    BasicErrorResponse:
      type: object
      properties:
        errors:
          type: array
          items:
            type: string
          description: One or more human-readable error messages.
        success:
          type: boolean
          description: >-
            Present (and `false`) on some endpoints (notifications, templates,
            segments). Not emitted by every endpoint.
        reference:
          type: array
          items:
            type: string
          description: >-
            Documentation URL fragments related to the error. Only emitted by
            the API-key auth error helpers.

````