Skip to main content
POST
/
players
/
csv_export
cURL
curl --request POST \
  --url https://api.onesignal.com/players/csv_export \
  --header 'Authorization: <authorization>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "extra_fields": [
    "external_user_id",
    "country",
    "timezone_id"
  ],
  "last_active_since": "<string>",
  "segment_name": "<string>",
  "include_unsubscribed": false
}
'
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;
}
}
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_API_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",
)

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)
<?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;
}
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)
}
require 'onesignal'
# setup authorization
OneSignal.configure do |config|
# Configure Bearer authorization: rest_api_key
config.rest_api_key = 'YOUR_REST_API_KEY'

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
// 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("YOUR_REST_API_KEY");

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();
}
}
}
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_REST_API_KEY";

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);
}
}
}
}
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),
}
}
{
  "csv_file_url": "<string>"
}
{
"errors": [
"Request is malformed: Failed to parse app_id from request"
]
}
{
"errors": [
"API rate limit exceeded"
]
}
{
"errors": [
"Service temporarily unavailable"
]
}

Overview

Use this endpoint to request a GZip-compressed CSV export of all your Subscriptions data 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:
200 OK
{
  "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)
404 CSV GET
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>
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.

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.
  • timezone_id: The user’s timezone in IANA format.

Headers

Authorization
string
default:Key YOUR_APP_API_KEY
required

Your App API key with prefix Key. See Keys & IDs.

Query Parameters

app_id
string
default:YOUR_APP_ID
required

Your OneSignal App ID in UUID v4 format. See Keys & IDs.

Body

application/json
extra_fields
enum<string>[]

Additional properties that you can include in the CSV.

Available options:
external_user_id,
onesignal_id,
location,
country,
rooted,
ip,
web_auth,
web_p256,
unsubscribed_at,
notification_types,
timezone_id
last_active_since
string

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
string

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
boolean
default:false

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.

Response

200

csv_file_url
string

The URL to download the CSV file. The file is available for 3 days after generation.