User-defined report schedules

After creating User-defined report templates, you must create schedules for those templates before you can generate one-time or recurring reports.

You can use the GraphQL and REST APIs to manage report schedules. The following table lists the report schedule tasks you can accomplish with these APIs.

Report Schedule Task GraphQL REST
Create a report schedule. Yes Yes
Cancel a report being processed. Yes No
Rerun a report even if the recurring schedule is complete. Yes No
Delete a report schedule. Yes Yes
Update a current schedule. Yes No
Retrieve past report schedules. Yes Yes

Here's what you need to know about report schedules regardless of which API you use:

Report schedules in GraphQL

NOTE: This section is intended for advertisers in The Trade Desk platform who want to manage report schedules using GraphQL. If you are a vendor providing reporting services on the advertiser's behalf, you must use the REST API to schedule reports.

The following table lists the tasks for retrieving and managing reports and their schedules.

Task Query or Mutation Notes
Schedule a recurring report. myReportsTemplateScheduleCreate You can schedule daily, weekly, monthly, and quarterly recurring reports.
Generate a one-time report. myReportsTemplateScheduleCreate None.
Run a recurring report immediately. myReportsReportScheduleCreate mutation All mutations require the report schedule ID that you can retrieve using the myReportsReportSchedules query.
Retrieve report and schedule details. myReportsReportSchedules query
myReportsReportSchedule query
Use these queries to retrieve report status, IDs, download links, and other details, and to apply filters as needed.
Update a recurring report schedule. myReportsReportScheduleUpdate mutation Use this mutation to disable report schedules or to activate disabled ones.
Cancel a report in progress. myReportsReportExecutionCancel mutation Use this mutation to cancel a report before it is processed.
Delete a recurring report schedule. myReportsReportScheduleDelete mutation None.

Schedule a recurring report

To schedule a recurring report, use the GraphQL myReportsTemplateScheduleCreate mutation. Include the report template ID and set the frequency value to define the cadence. The following example shows how to schedule a weekly report.

IMPORTANT: The download link requires an API token. To retrieve a regular link you can click to download the report without authentication, include the emails field and send the report to an email address.

mutation {
  myReportsTemplateScheduleCreate(
    input: {
      templateId: "4711075"
      reportName: "REPORT_NAME_PLACEHOLDER"
      startDate: "2025-10-10T00:00:00Z"
      frequency: WEEKLY
      dateRange: LAST14_DAYS
      timezone: UTC
      format: EXCEL
      includeHeaders: true
      dateFormat: US
      numericFormat: US
      emails: ["EMAIL_ADDRESS_PLACEHOLDER"]
      reportFilters: [
        { reportType: "1", partnerIds: ["PARTNER_ID_PLACEHOLDER"] }
        { reportType: "10", partnerIds: ["PARTNER_ID_PLACEHOLDER"] }
      ]
      conversionMetricOrdering: ALPHABETICALLY_BY_COLUMN_NAMES
      tailAggregations: [{ columnId: 15, tailAggregation: NO_IMPRESSIONS }]
      suppressTotals: false
      suppressZeroMeasureRows: false
    }
  ) {
    data {
      scheduleId
    }
    errors {
      __typename
      ... on MutationError {
        field
        message
      }
    }
  }
}

Generate a one-time report

To generate a one-time report, use the GraphQL myReportsTemplateScheduleCreate mutation. Include the report template ID and set the frequency value to SINGLE_RUN.

IMPORTANT: The download link requires an API token. To retrieve a regular link you can click to download the report without authentication, include the emails field and send the report to an email address.

mutation {
  myReportsTemplateScheduleCreate(
    input: {
      templateId: "4711075"
      reportName: "REPORT_NAME_PLACEHOLDER"
      startDate: "2025-10-10T00:00:00Z"
      frequency: SINGLE_RUN
      dateRange: LAST14_DAYS
      timezone: UTC
      format: EXCEL
      includeHeaders: true
      dateFormat: US
      numericFormat: US
      emails: ["EMAIL_ADDRESS_PLACEHOLDER"]
      reportFilters: [
        { reportType: "1", partnerIds: ["PARTNER_ID_PLACEHOLDER"] }
        { reportType: "10", partnerIds: ["PARTNER_ID_PLACEHOLDER"] }
      ]
      conversionMetricOrdering: ALPHABETICALLY_BY_COLUMN_NAMES
      tailAggregations: [{ columnId: 15, tailAggregation: NO_IMPRESSIONS }]
      suppressTotals: false
      suppressZeroMeasureRows: false
    }
  ) {
    data {
      scheduleId
    }
    errors {
      __typename
      ... on MutationError {
        field
        message
      }
    }
  }
}

Retrieve report and schedule details

To retrieve a list of reports and their schedules, processing statuses, and other details, use the GraphQL myReportsReportSchedules query. Here's what you need to know about this query:

Here's an example of how to retrieve reports based on the last status change date. This also returns a list of schedule IDs in the nodes.id field.

query GetReportDetailsExample {
  myReportsReportSchedules(
    where: {
      executions: { some: { lastStatusChangeDate: { gte: "2025-07-01" } } }
    }
  ) {
    nodes {
      id
      name
      status
      filters {
        advertiserFilters {
          name
        }
        partnerFilters {
          name
        }
      }
      timezone
      executions {
        nodes {
          id
          reportStartDateInclusive
          reportEndDateExclusive
          lastStatusChangeDate
          state
          delivery {
            downloadLink
            deliveredDate
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Here's an example of retrieving a single report with a schedule ID.

query GetSingleReportDetailsExample {
  myReportsReportSchedule(id: "REPORT_SCHEDULE_ID_PLACEHOLDER") {
    status
    filters {
      advertiserFilters {
        name
      }
      partnerFilters {
        name
      }
    }
    executions {
      nodes {
        id
        reportStartDateInclusive
        reportEndDateExclusive
        lastStatusChangeDate
        state
        delivery {
          downloadLink
          deliveredDate
        }
      }
    }
  }
}

Report statuses (states)

The following table lists the possible values for the state field.

State Value Description
CANCELED The system or user stopped the report file from being generated.
COMPLETED The report file generated successfully and is ready for download.
FAILED The system could not generate the report due to an error.
IN_PROGRESS The system is currently generating the report file.
WAITING_FOR_DEPENDENCIES The report file is on hold while waiting for required data or other resources.
WAITING_FOR_EXECUTION The report is queued and waiting to start generation.
WAITING_FOR_FAILURE_HANDLING The report file failed to generate due to an error and is waiting for failure resolution.
WAITING_FOR_RETRY_AFTER_FAILURE The report file failed to generate and is waiting to retry.

Update a report schedule

To activate a disabled report or disable an active report, use the myReportsReportScheduleUpdate mutation, include the report ID, and set the status to either ACTIVE or DISABLED.

mutation GeneratedTabDisableSchedule {
  myReportsReportScheduleUpdate(
    input: { reportScheduleId: "REPORT_SCHEDULE_ID_PLACEHOLDER", status: DISABLED }
  ) {
    data {
      id
      status
    }
    errors {
      __typename
      ... on MutationError {
        field
        message
      }
    }
  }
}

Cancel a report in progress

To cancel a report that is currently being processed by the system, use the myReportsReportExecutionCancel mutation and include the report schedule ID. For details about retrieving the schedule ID, see Retrieve report information.

mutation {
  myReportsReportExecutionCancel(input: {
     executionId: "REPORT_SCHEDULE_ID_PLACEHOLDER"
  }) {
    data {
      isCancelled
    }
    errors {
      __typename
      ... on MutationError {
        field
        message
      }
    }
  }
}

Run an existing scheduled report

You might want to rerun a report for the following reasons:

NOTE: If you make updates to a report schedule, you will create a new schedule.

To run a report from an existing schedule, use the myReportsReportScheduleCreate mutation and include the report ID you retrieved.

mutation {
  myReportsReportScheduleCreate(
    input: {
      singleRunFromExistingScheduleInput: {
        id: "REPORT_SCHEDULE_ID_PLACEHOLDER"
      }
    }
  ) {
    data {
      id
    }
    errors {
      __typename
      ... on MutationError {
        field
        message
      }
    }
  }
}

Delete a recurring schedule

To delete a recurring report schedule, use the myReportsReportScheduleDelete mutation and include the ID of the report you retrieved.

NOTE: If you delete a report schedule, you can still access the report.

mutation {
  myReportsReportScheduleDelete(input: {
    reportScheduleId: "REPORT_SCHEDULE_ID_PLACEHOLDER",
  }) {
    data {
      isDeleted
    }
    errors {
      __typename
      ... on MutationError {
        field
        message
      }
    }
  }
}

Report schedules in REST

The following diagram describes the process of retrieving user-defined reports using the My Reports REST API.

For details on querying for template headers and scheduling reports, see Create and manage report schedules.

Create a report schedule

To create a report schedule, use the POST /myreports/reportschedule endpoint.

Best practices

Here's what you need to keep in mind when creating reports:

Request

The following is a JSON example of a POST /myreports/reportschedule request.

{
  "ReportScheduleName": "Adgroup Performance Report HD",
  "RequestedByUserName": "jane.doe@companyemail.com",
  "ReportTemplateId": 168005,
  "IsCompleted": true,
  "ReportScheduleStatus": "Disabled",
  "ReportFileFormat": "TSV",
  "PartnerFilters": [
    "partner123abc"
  ],
  "ReportDateRange": "LastXDays",
  "TimeZone": "UTC",
  "ReportDateFormat": "International",
  "ReportNumericFormat": "US",
  "IncludeHeaders": true,
  "LookbackDays": 1,
  "ReportFrequency": "Daily",
  "ConversionPixelNames": [
    {
      "AdvertiserId": "adv890xyz",
      "ConversionPixelName": "Generic Inc Friends Conversion",
      "ConversionType": "abc123", // This is the tracking tag ID.
      "CrossDeviceAttributionModelId": "IdentityAlliance"
    },
    {
      "AdvertiserId": "adv890xyz",
      "ConversionPixelName": "Landing Page Visit",
      "ConversionType": "234def", // This is the tracking tag ID.
      "CrossDeviceAttributionModelId": "IdentityAlliance"
    },
    {
      "AdvertiserId": "adv890xyz",
      "ConversionPixelName": "Inferred Brand Impact",
      "ConversionType": "123abc", // This is the tracking tag ID.
      "CrossDeviceAttributionModelId": "IdentityAlliance"
    }
  ]  
}

Response

The following is an example of a POST /myreports/reportschedule response with the newly created report schedule.

{
   "ReportScheduleId":654321,
   "ReportScheduleName":"PartnerID Adgroup Performance Report HD",
   "ReportTemplateId":168005,
   "ReportFileFormat":"TSV",
   "PartnerFilters":[
      "partner123abc"
   ],
   "ReportDateRange":"LastXDays",
   "TimeZone":"UTC",
   "ReportDateFormat":"International",
   "ReportNumericFormat":"US",
   "IncludeHeaders":true,
   "LookbackDays":1,
   "ReportFrequency":"Daily",
   "ConversionPixelNames":[
      {
         "AdvertiserId":"adv890xyz",
         "ConversionPixelName":"Generic Inc Friends Conversion",
         "ConversionType":"abc123",
         "CrossDeviceAttributionModelId":"IdentityAlliance"
      },
      {
         "AdvertiserId":"adv890xyz",
         "ConversionPixelName":"Landing Page Visit",
         "ConversionType":"234def",
         "CrossDeviceAttributionModelId":"IdentityAlliance"
      },
      {
         "AdvertiserId":"adv890xyz",
         "ConversionPixelName":"Inferred Brand Impact",
         "ConversionType":"123abc",
         "CrossDeviceAttributionModelId":"IdentityAlliance"
      }
   ]
}

Best practices for custom report start and end dates

When setting a custom date range for your report, ensure that the start and end dates that you specify cover the date range you want.

The following table provides examples of different date ranges.

Start Date Inclusive End DAte Exclusinve Date Range Report Duration
May 1 June 1 May 1 - May 31 Full month report.
May 1 May 31 May 1 - May 30 Nearly a full month report but the last day is excluded since EndDateExclusive drops the last date in the range.
May 1 May 1 No data Zero days. To get a one-day report for May 1, the date range should be May 1 - May 2. See also Best practices.

The following sections describe the report execution and retrieval steps illustrated in the diagram.

Retrieve a report

Here's what you need to know when using the report execution endpoints:

TIP: Download a Python code sample that demonstrates recommended call patterns and best practices for this process. Use it as a starting point for testing in your sandbox environment.

To retrieve a report, complete the following steps.

Step Description Endpoint
1 Retrieve a download URL for the report. Depending on the report level, use one of the following endpoints:
  • POST /v3/myreports/reportexecution/query/partners
  • POST /v3/myreports/reportexecution/query/advertisers
2 Download report data using the obtained download URL. GET "REPORT_DOWNLOAD_URL_PLACEHOLDER"

Retrieve a download URL for your report

The following is an example of a POST/v3/myreports/reportexecution/query/partners request with a placeholder for your API token. It retrieves any partner-wide reports for the given date.

curl -H "Content-Type: application/json" -H "TTD-Auth:API_TOKEN_PLACEHOLDER" -X POST "https://api.thetradedesk.com/v3/myreports/reportexecution/query/partners" -d '{"PartnerIds": ["PARTNER_ID_PLACEHOLDER"], "ExecutionStates": ["Complete"], "ExecutionSpansStartDate": "2019-06-20T00:00:00.4837693+00:00", "PageStartIndex": 0, "PageSize": 10}'

The following is an example of a POST /v3/myreports/reportexecution/query/partners response with the report download URL.

{
    "Result":[
       {
          "ReportExecutionId":8247483,
          "ReportExecutionState":"Complete",
          "LastStateChangeUTC":"2019-06-21T03:32:33.073",
          "DisabledReason":null,
          "Timezone":"UTC",
          "ReportStartDateInclusive":"2019-06-07T00:00:00",
          "ReportEndDateExclusive":"2019-06-21T00:00:00",
          "ReportScheduleName":"Daily Report",
          "ReportDeliveries":[
             {
                "ReportDestination":"EmailedS3Link",
                "DeliveredPath":"thetradedesk-useast-hdreports/scheduled/2019/06/07/SpotX_NGL - Daily Report_18323/Daily Report/ Daily Report NGL_2019-06-07_8247483.tsv",
                "DeliveredUTC":"2019-06-21T03:32:33.027",
                "DownloadURL":"api.thetradedesk.com/v3/reports/download/{EXECUTION_ID}/{DELIVERY_ID}?t={TIMESTAMP}&s={SIGNATURE}&src={SOURCE}", // The system will replace placeholders in curly braces with actual values.
                "DownloadURLExpirationUTC":"2019-06-22T20:27:14.6448956Z"
             }
          ]
       }
    ],
    "ResultCount":1,
    "TotalFilteredCount":1
 }

Download report data

Here's the request syntax for downloading reports with placeholders for your API token and the report download URL:

curl -H "TTD-Auth:API_TOKEN_PLACEHOLDER" -X GET "REPORT_DOWNLOAD_URL_PLACEHOLDER"

The following is an example of a request to view report data with a placeholder for your API token and the download URL returned in the preceding response example. The returned URL will have actual values instead of the placeholders shown in curly braces.

curl -H "TTD-Auth:API_TOKEN_PLACEHOLDER" -X GET "api.thetradedesk.com/v3/reports/download/{EXECUTION_ID}/{DELIVERY_ID}?t={TIMESTAMP}&s={SIGNATURE}&src={SOURCE}"

A successful response returns the contents of the report.

Report filtering

Based on the ReportExecutionStates, ReportScheduleIds, pagination, and other parameters that you specify in the My Reports execution endpoints, reports are filtered from the most general parameters like PageSize to more specific ones like ReportScheduleIds.

The following diagram illustrates the filtering process.

Report execution spans start and end dates

The following table provides guidelines and examples on setting the optional ExecutionSpansStartDate and ExecutionSpansEndDate values in the My Reports execution endpoints.

NOTE: The reporting range refers to the range of data included in a report.

Property Value Description Example
ExecutionSpansStartDate Any date prior to the end of the reporting range of your report request. To pull a week-long report with data from August 1–7, set this parameter to any date on or prior to August 7.
ExecutionSpansEndDate Any date after the start of the reporting range of your report request. To pull a week-long report with data from August 1–7, set this parameter to any date on or after August 1.

The following table provides more examples, which assume that you have a daily report set to deliver one day’s worth of data and that today is August 7.

Data Wanted Execution Span Start date Execution Span End date
All reports that have been run with yesterday’s data (August 6) August 6 August 6
Reports containing data for August 5, 6, and 7 August 5 August 7
Reports containing data from before August 7 August 7 Do not specify
Reports containing all data from August 1 Do not specify August 1
All reports for all date ranges Do not specify Do not specify

FAQs

The following are frequently asked questions about report processing.

If I rerun a report for the last seven days, will it include data from the original time period or from the most recent seven days?

The regenerated report will use the most recent seven days and will end on the day you regenerated the report. For example, if you rerun a report on July 7 at 10:00 a.m., and the lookback window is 7 days, the report will include data from June 30 at 12:00 a.m. to July 7 at 12:00 a.m. based on the report’s time zone.

Can I cancel a report that is currently processing?

Yes. For details, see Cancel a report in progress.

Why was my report schedule automatically disabled?

The Trade Desk automatically disables a recurring report schedule in either of the following cases:

In both cases, you receive a warning email two weeks before the schedule is disabled. To check whether a schedule was automatically disabled by the system, use the myReportsReportSchedules query and include the isAdminDisabled and disabledMessage fields. For details on how to reactivate a disabled schedule, see Update a report schedule.

Are all report schedules subject to being automatically disabled?

No. Here are the schedule types that do not get automatically disabled:

If I lost the email that contains the download link for my report, how do I retrieve it?

Use the GraphQL myReportsReportSchedules query and include the downloadLink field. Note that this query returns an API download link, which requires an API token. To retrieve a regular link you can click to download the report without authentication, create a schedule and include an email address.

How do I get a new download link if my original one expired?

Use the myReportsReportScheduleCreate mutation to run the report immediately.

Can I search for campaigns based on the filters I create?

Yes. To retrieve a list of campaigns by the labels you created, use the advertiser query and include the customLabels field. The following is a GraphQL example for retrieving campaigns that have a specific custom label.

query Advertiser {
  advertiser(id: "ADVERTISER_ID_PLACEHOLDER") {
    campaigns {
      edges {
        node {
          id
          name
          customLabels(
            where: { id: { eq: "CUSTOM_LABEL_PLACEHOLDER" } }
          ) {
            nodes {
              id
              name
            }
          }
        }
      }
    }
  }
}