> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.getdial.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.getdial.ai/_mcp/server.

# Change the subscription billing interval

POST https://getdial.ai/api/v1/billing/subscription/change
Content-Type: application/json

Switches the subscription billing interval (e.g. upgrade monthly → annual). Prorated and invoiced immediately; the new-period entitlement lands when that invoice is paid. Clears any scheduled cancellation. No-op if already on the target interval. Not available during impersonation.

Reference: https://docs.getdial.ai/api-reference/rest-api/billing/change-subscription-interval

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: rest
  version: 1.0.0
paths:
  /api/v1/billing/subscription/change:
    post:
      operationId: change-subscription-interval
      summary: Change the subscription billing interval
      description: >-
        Switches the subscription billing interval (e.g. upgrade monthly →
        annual). Prorated and invoiced immediately; the new-period entitlement
        lands when that invoice is paid. Clears any scheduled cancellation.
        No-op if already on the target interval. Not available during
        impersonation.
      tags:
        - subpackage_billing
      parameters:
        - name: Authorization
          in: header
          description: 'Your Dial API key, sent as `Authorization: Bearer sk_live_...`'
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Interval change applied (or already on the target interval).
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Billing_changeSubscriptionInterval_Response_200
        '400':
          description: The request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                interval:
                  $ref: >-
                    #/components/schemas/ApiV1BillingSubscriptionChangePostRequestBodyContentApplicationJsonSchemaInterval
                promotionCode:
                  type: string
                  description: >-
                    Optional customer-facing promotion code (e.g. `LAUNCH20`) to
                    apply to the subscription. Resolved to its Stripe promotion
                    code and handed to Stripe, which validates it and applies
                    the discount per the underlying coupon's own scope and
                    duration. An invalid, expired, or inapplicable code is
                    rejected with `400`. Preview the discounted amount first
                    with Preview a subscription change.
                prorationDate:
                  type: integer
                  description: >-
                    Optional Unix timestamp (seconds) from a prior preview's
                    `prorationDate`. When supplied, the proration is calculated
                    as of that instant so the charged amount matches the
                    previewed quote exactly. Omit to prorate as of now.
              required:
                - interval
servers:
  - url: https://getdial.ai
    description: Dial API (provisional host)
components:
  schemas:
    ApiV1BillingSubscriptionChangePostRequestBodyContentApplicationJsonSchemaInterval:
      type: string
      enum:
        - monthly
        - annual
      title: >-
        ApiV1BillingSubscriptionChangePostRequestBodyContentApplicationJsonSchemaInterval
    ApiV1BillingSubscriptionChangePostResponsesContentApplicationJsonSchemaInterval:
      type: string
      enum:
        - monthly
        - annual
      title: >-
        ApiV1BillingSubscriptionChangePostResponsesContentApplicationJsonSchemaInterval
    Billing_changeSubscriptionInterval_Response_200:
      type: object
      properties:
        changed:
          type: boolean
          description: False when already on the target interval.
        interval:
          $ref: >-
            #/components/schemas/ApiV1BillingSubscriptionChangePostResponsesContentApplicationJsonSchemaInterval
      title: Billing_changeSubscriptionInterval_Response_200
    ErrorError:
      oneOf:
        - type: string
        - type: object
          additionalProperties:
            description: Any type
      description: An error message, or a validation-error object for 400 responses.
      title: ErrorError
    Error:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorError'
          description: An error message, or a validation-error object for 400 responses.
      title: Error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Your Dial API key, sent as `Authorization: Bearer sk_live_...`'

```

## Examples



**Request**

```json
{
  "interval": "annual"
}
```

**Response**

```json
{
  "changed": true,
  "interval": "annual"
}
```

**SDK Code**

```python
import requests

url = "https://getdial.ai/api/v1/billing/subscription/change"

payload = { "interval": "annual" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://getdial.ai/api/v1/billing/subscription/change';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"interval":"annual"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://getdial.ai/api/v1/billing/subscription/change"

	payload := strings.NewReader("{\n  \"interval\": \"annual\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://getdial.ai/api/v1/billing/subscription/change")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"interval\": \"annual\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://getdial.ai/api/v1/billing/subscription/change")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"interval\": \"annual\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://getdial.ai/api/v1/billing/subscription/change', [
  'body' => '{
  "interval": "annual"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://getdial.ai/api/v1/billing/subscription/change");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"interval\": \"annual\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["interval": "annual"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://getdial.ai/api/v1/billing/subscription/change")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```