6 min read

Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.

POST /ads-management/v1/campaigns — openapi

Create a campaign

Creates an ad campaign in the billing account. The creatives you reference must already exist as Open Cloud image assets that you have permission to use; they are validated and saved to your account's reusable creatives when the campaign is created. On success the campaign is returned with deliveryStatus IN_REVIEW, meaning it is queued for ad-policy review and not yet serving — poll the campaign (or campaigns:batchGetStatus) until this changes. budget.amountMicros is the budget in micro-USD as a decimal string (e.g. "5000000" = $5.00). It must be at least the minimum campaign budget; an amount below the minimum returns 400 with the required minimum stated in the error message. schedule.durationInDays must not exceed 3650 (~10 years). The x-idempotency-key header is required and must be a UUID: retrying the same key with an identical body within 24 hours returns the original campaign (200), while reusing a key with a different body returns 409.

Endpoint

Method: POST

Path: /ads-management/v1/campaigns

Servers:

Parameters

NameLocationRequiredDescription
x-idempotency-keyheadertrueIdempotency key (UUID); 24h dedupe window. Identical replay returns the original campaign (200); mismatched replay may conflict (409).
[
  {
    "description": "Idempotency key (UUID); 24h dedupe window. Identical replay returns the original campaign (200); mismatched replay may conflict (409).",
    "name": "x-idempotency-key",
    "in": "header",
    "required": true,
    "schema": {
      "type": "string"
    }
  }
]

Request Body

Campaign creation request

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/internal_public_v1.CreateCampaignRequest"
      }
    }
  },
  "description": "Campaign creation request",
  "required": true
}

Responses

StatusDescription
200Campaign created, or idempotent replay of a prior create with the same key and body
400Validation error, invalid asset, or endTime sent
403Cannot manage account, universe not advertisable, or USE-permission denied
409Idempotency key reused with a different request body, or concurrent write conflict
429Rate limit exceeded
500Internal server error
{
  "200": {
    "description": "Campaign created, or idempotent replay of a prior create with the same key and body",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.Campaign"
        }
      }
    }
  },
  "400": {
    "description": "Validation error, invalid asset, or endTime sent",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
        }
      }
    }
  },
  "403": {
    "description": "Cannot manage account, universe not advertisable, or USE-permission denied",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
        }
      }
    }
  },
  "409": {
    "description": "Idempotency key reused with a different request body, or concurrent write conflict",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
        }
      }
    }
  },
  "429": {
    "description": "Rate limit exceeded",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
        }
      }
    }
  },
  "500": {
    "description": "Internal server error",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
        }
      }
    }
  }
}

Authentication

{
  "security": [
    {
      "roblox-legacy-cookie": []
    },
    {
      "roblox-api-key": []
    },
    {
      "roblox-oauth2": [
        "ad.campaign:write"
      ]
    }
  ],
  "securitySchemes": {
    "roblox-api-key": {
      "type": "apiKey",
      "description": "A configurable key that allows granular access to Roblox resources. See https://create.roblox.com/docs/cloud/auth/api-keys for more information.",
      "name": "x-api-key",
      "in": "header"
    },
    "roblox-legacy-cookie": {
      "type": "apiKey",
      "description": "A browser cookie that represents the identity of a Roblox user. DO NOT SHARE THIS. Sharing this will allow someone to log in as you and to steal your Robux and items. We do not recommend using cookies to call endpoints. When possible, use API keys with the x-api-key header or OAuth 2.0 instead for authentication.",
      "in": "cookie",
      "name": ".ROBLOSECURITY"
    },
    "roblox-oauth2": {
      "type": "oauth2",
      "description": "Build or authorize apps to access Roblox resources. See https://create.roblox.com/docs/cloud/auth/oauth2-overview for more information.",
      "flows": {
        "authorizationCode": {
          "authorizationUrl": "https://apis.roblox.com/oauth/v1/authorize",
          "tokenUrl": "https://apis.roblox.com/oauth/v1/token",
          "refreshUrl": "https://apis.roblox.com/oauth/v1/token",
          "scopes": {}
        }
      }
    }
  }
}

Complete Operation Definition

{
  "description": "Creates an ad campaign in the billing account. The creatives you reference must already exist as Open Cloud image assets that you have permission to use; they are validated and saved to your account's reusable creatives when the campaign is created. On success the campaign is returned with deliveryStatus IN_REVIEW, meaning it is queued for ad-policy review and not yet serving — poll the campaign (or campaigns:batchGetStatus) until this changes. budget.amountMicros is the budget in micro-USD as a decimal string (e.g. \"5000000\" = $5.00). It must be at least the minimum campaign budget; an amount below the minimum returns 400 with the required minimum stated in the error message. schedule.durationInDays must not exceed 3650 (~10 years). The x-idempotency-key header is required and must be a UUID: retrying the same key with an identical body within 24 hours returns the original campaign (200), while reusing a key with a different body returns 409.",
  "tags": [
    "Advertising"
  ],
  "summary": "Create a campaign",
  "parameters": [
    {
      "description": "Idempotency key (UUID); 24h dedupe window. Identical replay returns the original campaign (200); mismatched replay may conflict (409).",
      "name": "x-idempotency-key",
      "in": "header",
      "required": true,
      "schema": {
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/internal_public_v1.CreateCampaignRequest"
        }
      }
    },
    "description": "Campaign creation request",
    "required": true
  },
  "responses": {
    "200": {
      "description": "Campaign created, or idempotent replay of a prior create with the same key and body",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/internal_public_v1.Campaign"
          }
        }
      }
    },
    "400": {
      "description": "Validation error, invalid asset, or endTime sent",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
          }
        }
      }
    },
    "403": {
      "description": "Cannot manage account, universe not advertisable, or USE-permission denied",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
          }
        }
      }
    },
    "409": {
      "description": "Idempotency key reused with a different request body, or concurrent write conflict",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
          }
        }
      }
    },
    "429": {
      "description": "Rate limit exceeded",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
          }
        }
      }
    },
    "500": {
      "description": "Internal server error",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/internal_public_v1.ErrorEnvelope"
          }
        }
      }
    }
  },
  "x-roblox-stability": "EXPERIMENTAL",
  "x-roblox-rate-limits": {
    "perApiKeyOwner": {
      "period": "MINUTE",
      "maxInPeriod": 60
    },
    "perOauth2Authorization": {
      "period": "MINUTE",
      "maxInPeriod": 60
    }
  },
  "x-roblox-scopes": [
    {
      "name": "ad.campaign:write",
      "targetResourceSpecifier": ""
    }
  ],
  "x-roblox-engine-usability": {
    "apiKeyWithHttpService": false
  },
  "security": [
    {
      "roblox-legacy-cookie": []
    },
    {
      "roblox-api-key": []
    },
    {
      "roblox-oauth2": [
        "ad.campaign:write"
      ]
    }
  ],
  "externalDocs": {
    "url": "https://create.roblox.com/docs/cloud/reference/features/advertising#post_ads_management_v1_campaigns"
  }
}