Skip to content

Base API

Base endpoint for pull zones, video libraries, storage zones, billing, support, and more.
Everything that can be done with the control panel can also be achieved with the API.

Setup

<?php

require 'vendor/autoload.php';

use ToshY\BunnyNet\BaseAPI;
use ToshY\BunnyNet\Client\BunnyClient;

$bunnyClient = new BunnyClient(
    client: new \Symfony\Component\HttpClient\Psr18Client(),
);

// Provide the account API key.
$baseApi = new BaseAPI(
    apiKey: '2cebf4f8-4bff-429f-86f6-bce2c2163d7e89fb0a86-a1b2-463c-a142-11eba8811989',
    client: $bunnyClient,
);

Usage

Abuse Case

List Abuse Cases

$baseApi->listAbuseCases(
    query: [
        'page' => 1,
        'perPage' => 1000,
    ],
);

Get DMCA Case

$baseApi->getDmcaCase(
    id: 1,
);

Warning

  • This endpoint currently returns a 401 status code.

Get Abuse Case

$baseApi->getAbuseCase(
    id: 1,
);

Warning

  • This endpoint currently returns a 401 status code.

Resolve DMCA Case

$baseApi->resolveDmcaCase(
    id: 1,
);

Resolve Abuse Case

$baseApi->resolveAbuseCase(
    id: 1,
);

Check Abuse Case

$baseApi->checkAbuseCase(
    id: 1,
);

Countries

List Countries

$baseApi->listCountries();

API Keys

List API Keys

$baseApi->listApiKeys(
    query: [
        'page' => 1,
        'perPage' => 1000,
    ],
);

Warning

  • This endpoint currently returns a 500 status code with the following response:
    {"Message":"Authorization has been denied for this request."}

Billing

Get Billing Details

$baseApi->getBillingDetails();

Configure Auto Recharge

$baseApi->configureAutoRecharge(
    body: [
        'AutoRechargeEnabled' => true,
        'PaymentMethodToken' => 1000,
        'PaymentAmount' => 10,
        'RechargeTreshold' => 2,
    ],
);

Note

  • The key RechargeTreshold (misspelled) has a value range of 2-2000.
  • The key PaymentAmount has a value range of 10-2000.

Create Payment Checkout

$baseApi->createPaymentCheckout(
    body: [
        'RechargeAmount' => 10,
        'PaymentAmount' => 10,
        'PaymentRequestId' => 123456,
        'Nonce' => 'ab',
    ],
);

Note

  • The key PaymentAmount has a value range of 10-2000.

Prepare Payment Authorization

$baseApi->preparePaymentAuthorization();

Get Affiliate Details

$baseApi->getAffiliateDetails();

Claim Affiliate Credits

$baseApi->claimAffiliateCredits();

Get The Coinify Bitcoin exchange rate

$baseApi->getCoinifyBitcoinExchangeRate();

Create Coinify payment

$baseApi->createCoinifyPayment(
    query: [
        'amount' => 123,
    ],
);

Get Billing Summary

$baseApi->getBillingSummary();

Get Billing Summary PDF

$baseApi->getBillingSummaryPdf(
    billingRecordId: 1,
);

Apply Promo Code

$baseApi->applyPromoCode(
    query: [
        'CouponCode' => 'YOUFOUNDME',
    ],
);

Support

List Tickets

$baseApi->listTickets(
    query: [
        'page' => 1,
        'perPage' => 1000,
    ],
);

Get Ticket Details

$baseApi->getTicketDetails(
    id: 1,
);

Close Ticket

$baseApi->closeTicket(
    id: 1,
);

Reply Ticket

$baseApi->closeTicket(
    id: 1,
    body: [
        'Message' => 'Hope you are having a nice day!\n\nThe weather is nice outside.',
        'Attachments' => [
            [
                'Body' => 'aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ==',
                'FileName' => 'details.txt',
                'ContentType' => 'text/plain',
            ],
        ],
    ],
);

Note

  • The key Body requires its contents to be base64 encoded.

Create Ticket

$baseApi->createTicket(
    id: 1,
    body: [
        'Subject' => 'Good day!',
        'LinkedPullZone' => 1,
        'Message' => 'Hope you are having a nice day!\n\nThe weather is nice outside.',
        'LinkedStorageZone' => 2,
        'Attachments' => [
            [
                'Body' => 'aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ==',
                'FileName' => 'details.txt',
                'ContentType' => 'text/plain',
            ],
        ],
    ],
);

Note

  • The keys LinkedPullZone and LinkedStorageZone are not required unlike stated in the API specifications.
  • The key Body requires its contents to be base64 encoded.

DRM Certificate

List DRM Certificates

$baseApi->listDrmCertificates(
    query: [
        'page' => 1,
        'perPage' => 1000,
    ],
);

Warning

  • This endpoint currently returns a 500 status code with the following response:
    {"Message":"An error has occurred."}
    A support ticket has been created at bunny.net regarding this issue.

Integrations

Get GitHub Integration

$baseApi->getGitHubIntegration();

Warning

This endpoint is (currently) undocumented.

Info

This endpoint returns the following response:

{
  "Accounts": [
    {
      "Id": 1,
      "Name": "MyConnectedGitHubUsername"
    }
  ]
}
The id can be used as IntegrationId for the Add Edge Script endpoint.

Region

List Regions

$baseApi->listRegions();

Stream Video Library

List Video Libraries

$baseApi->listVideoLibraries(
    query: [
        'page' => 0,
        'perPage' => 1000,
        'search' => 'bunny',
        'includeAccessKey' => false,
    ],
);

Note

  • The key search is currently not functional.

Add Video Library

$baseApi->addVideoLibrary(
    body: [
        'Name' => 'New Video Library',
        'ReplicationRegions' => [
            'UK',
            'SE',
            'NY',
            'LA',
            'SG',
            'SYD',
            'BR',
            'JH',
        ],
    ],
);

Note

  • The key ReplicationRegions has the following possible values:
    • UK = London (United Kingdom)
    • SE = Norway (Stockholm)
    • NY = New York (United States East)
    • LA = Los Angeles (United States West)
    • SG = Singapore (Singapore)
    • SYD = Sydney (Oceania)
    • BR = Sao Paulo (Brazil)
    • JH = Johannesburg (Africa)

Get Video Library

$baseApi->getVideoLibrary(
    id: 1,
    query: [
        'includeAccessKey' => false,
    ],
);

Update Video Library

$baseApi->updateVideoLibrary(
    id: 1,
    body: [
        'Name' => 'New Video Library V2',
        'CustomHTML' => '<style>.plyr--full-ui input[type=range]{color: purple}</style>',
        'PlayerKeyColor' => '6a329f',
        'EnableTokenAuthentication' => true,
        'EnableTokenIPVerification' => false,
        'ResetToken' => false,
        'WatermarkPositionLeft' => 0,
        'WatermarkPositionTop' => 0,
        'WatermarkWidth' => 0,
        'WatermarkHeight' => 0,
        'EnabledResolutions' => '720p,1080p,1440p,2160p',
        'ViAiPublisherId' => '',
        'VastTagUrl' => '',
        'WebhookUrl' => 'https://example.com/video-status',
        'CaptionsFontSize' => 20,
        'CaptionsFontColor' => 'white',
        'CaptionsBackground' => 'black',
        'UILanguage' => 'GR',
        'AllowEarlyPlay' => true,
        'PlayerTokenAuthenticationEnabled' => true,
        'BlockNoneReferrer' => true,
        'EnableMP4Fallback' => true,
        'KeepOriginalFiles' => true,
        'AllowDirectPlay' => true,
        'EnableDRM' => false,
        'Controls' => 'play,progress,current-time,mute,volume,pip,fullscreen',
        'Bitrate240p' => 600,
        'Bitrate360p' => 800,
        'Bitrate480p' => 1400,
        'Bitrate720p' => 2800,
        'Bitrate1080p' => 5000,
        'Bitrate1440p' => 8000,
        'Bitrate2160p' => 25000,
        'ShowHeatmap' => false,
        'EnableContentTagging' => true,
        'FontFamily' => 'Arial',
        'EnableTranscribing' => false,
        'EnableTranscribingTitleGeneration' => false,
        'EnableTranscribingDescriptionGeneration' => false,
        'TranscribingCaptionLanguages' => [],
    ],
);

Note

  • The key EnabledResolutions has the following possible values (comma separated):
    • 240p
    • 360p
    • 480p
    • 720p
    • 1080p
    • 1440p
    • 2160p
  • The key Controls has the following possible values (comma separated):
    • play-large
    • play
    • progress
    • current-time
    • mute
    • volume
    • captions
    • settings
    • pip
    • airplay
    • fullscreen
  • To get a full list of possible value options for key TranscribingCaptionLanguages, see the Get Languages endpoint.

Delete Video Library

$baseApi->deleteVideoLibrary(
    id: 1,
);

Get Languages

$baseApi->getLanguages();

Reset Password

$baseApi->resetVideoLibraryPassword(
    query: [
        'id' => 1,
    ],
);

Reset Password (by path parameter)

$baseApi->resetVideoLibraryPasswordByPathParameter(
    id: 1,
);

Add Watermark

$baseApi->addWatermark(
    id: 1,
);

Delete Watermark

$baseApi->deleteWatermark(
    id: 1,
);

Add Allowed Referer

$baseApi->addVideoLibraryAllowedReferer(
    id: 1,
    body: [
        'Hostname' => '*.example.com,*.example.org',
    ],
);

Note

  • The key Hostname allows multiple values through comma separated values.

Remove Allowed Referer

$baseApi->removeVideoLibraryAllowedReferer(
    id: 1,
    body: [
        'Hostname' => '*.example.com',
    ],
);

Note

  • The key Hostname does not allow multiple values.

Add Blocked Referer

$baseApi->addVideoLibraryBlockedReferer(
    id: 1,
    body: [
        'Hostname' => 'evil.org',
    ],
);

Note

  • The key Hostname does not allow multiple values.

Remove Blocked Referer

$baseApi->removeVideoLibraryBlockedReferer(
    id: 1,
    body: [
        'Hostname' => 'evil.org',
    ],
);

Note

  • The key Hostname does not allow multiple values.

DNS Zone

List DNS Zones

$baseApi->listDnsZones(
    query: [
        'page' => 1,
        'perPage' => 1000,
        'search' => 'bunny.net',
    ],
);

Note

  • The key search can be used to filter on Id or Domain. A search value with an Id value will perform an exact match, whereas a search value with a Domain will perform a wildcard search: bunny, nny and .net will all match the DNS zone for bunny.net.

Add DNS Zone

$baseApi->addDnsZone(
    body: [
        'Domain' => 'example.com',
    ],
);

Get DNS Zone

$baseApi->getDnsZone(
    id: 1,
);

Update DNS Zone

$baseApi->updateDnsZone(
    id: 1,
    body: [
        'CustomNameserversEnabled' => true,
        'Nameserver1' => 'abbby.ns.cloudflare.com',
        'Nameserver2' => 'jonah.ns.cloudflare.com',
        'SoaEmail' => 'admin@example.com',
        'LoggingEnabled' => true,
        'LogAnonymizationType' => true,
        'LoggingIPAnonymizationEnabled' => true,
    ],
);

Note

  • The key LogAnonymizationType has the following possible values (undocumented):
    • 0 = Remove one octet
    • 1 = Drop IP
  • In order to disable LoggingIPAnonymizationEnabled you first need to agree to the DPA agreement (GDPR).

Delete DNS Zone

$baseApi->deleteDnsZone(
    id: 1,
);

Export DNS Zone

$baseApi->exportDnsZone(
    id: 1,
);

Get DNS Query Statistics

$baseApi->getDnsZoneQueryStatistics(
    id: 1,
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
    ],
);

Check DNS Zone Availability

$baseApi->checkDnsZoneAvailability(
    body: [
        'Name' => 'example.com',
    ],
);

Add DNS Record

$baseApi->addDnsRecord(
    zoneId: 1,
    body: [
        'Type' => 3,
        'Ttl' => 15,
        'Value' => 'My TXT Value',
        'Name' => '',
        'Weight' => 0,
        'Priority' => 0,
        'Flags' => 0,
        'Tag' => '',
        'Port' => 0,
        'PullZoneId' => 0,
        'ScriptId' => 0,
        'Accelerated' => false,
        'MonitorType' => 0,
        'GeolocationLatitude' => 0,
        'GeolocationLongitude' => 0,
        'LatencyZone' => null,
        'SmartRoutingType' => 0,
        'Disabled' => false,
        'EnviromentalVariables' => [
            [
                'Name' => 'Hello',
                'Value' => 'World',
            ],
        ],
        'Comment' => '',
    ],
);

Note

  • The key EnviromentalVariables is misspelled in the API specifications.
  • The key Type has the following possible values:
    • 0 = A
    • 1 = AAAA
    • 2 = CNAME
    • 3 = TXT
    • 4 = MX
    • 5 = RDR (Redirect)
    • 6 = Flatten
    • 7 = PZ (Pull Zone)
    • 8 = SRV
    • 9 = CAA
    • 10 = PTR
    • 11 = SCR (Script)
    • 12 = NS
  • The key TTL has the following possible values (in seconds):
    • 15
    • 30
    • 60 = 1 minute
    • 120 = 2 minutes
    • 300 = 5 minutes
    • 900 = 15 minutes
    • 1800 = 30 minutes
    • 3600 = 1 hour
    • 18000 = 5 hours
    • 43200 = 12 hours
    • 86400 = 1 day
  • The key ScriptId is not returned in the response.
  • The key MonitorType has the following possible values:
    • 0 = None
    • 1 = Ping
    • 2 = HTTP
    • 3 = Monitor
  • The key SmartRoutingType has the following possible values:
    • 0 = None
    • 1 = Latency
    • 2 = Geolocation

Update DNS Record

$baseApi->updateDnsRecord(
    zoneId: 1,
    id: 2,
    body: [
        'Type' => 3,
        'Ttl' => 15,
        'Value' => 'My TXT Value',
        'Name' => '',
        'Weight' => 0,
        'Priority' => 0,
        'Flags' => 0,
        'Tag' => '',
        'Port' => 0,
        'PullZoneId' => 0,
        'ScriptId' => 0,
        'Accelerated' => false,
        'MonitorType' => 0,
        'GeolocationLatitude' => 0,
        'GeolocationLongitude' => 0,
        'LatencyZone' => null,
        'SmartRoutingType' => 0,
        'Disabled' => false,
        'EnviromentalVariables' => [
            [
                'Name' => 'Hello',
                'Value' => 'World',
            ],
        ],
        'Comment' => '',
    ],
);

Note

  • The key EnviromentalVariables is misspelled in the API specifications.
  • The key Type has the following possible values:
    • 0 = A
    • 1 = AAAA
    • 2 = CNAME
    • 3 = TXT
    • 4 = MX
    • 5 = RDR (Redirect)
    • 6 = Flatten
    • 7 = PZ (Pull Zone)
    • 8 = SRV
    • 9 = CAA
    • 10 = PTR
    • 11 = SCR (Script)
    • 12 = NS
  • The key TTL has the following possible values (in seconds):
    • 15
    • 30
    • 60 = 1 minute
    • 120 = 2 minutes
    • 300 = 5 minutes
    • 900 = 15 minutes
    • 1800 = 30 minutes
    • 3600 = 1 hour
    • 18000 = 5 hours
    • 43200 = 12 hours
    • 86400 = 1 day
  • The key ScriptId is not returned in the response.
  • The key MonitorType has the following possible values:
    • 0 = None
    • 1 = Ping
    • 2 = HTTP
    • 3 = Monitor
  • The key SmartRoutingType has the following possible values:
    • 0 = None
    • 1 = Latency
    • 2 = Geolocation

Delete DNS Record

$baseApi->deleteDnsRecord(
    zoneId: 1,
    id: 2,
);

Recheck DNS Configuration

$baseApi->recheckDNSConfiguration(
    id: 1,
);

Dismiss DNS Configuration Notice

$baseApi->dismissDnsConfigurationNotice(
    id: 1,
);

Import DNS Records

/*
 * File contents read into string from the local filesystem.
 */
$content = file_get_contents('./example.com.2023-08-20.bind');

/*
 * File contents handle from a `$filesystem` (Flysystem FtpAdapter).
 */
$content = $filesystem->readStream('./example.com.2023-08-20.bind');

// Import DNS records.
$baseApi->importDnsRecords(
    zoneId: 1,
    body: $content,
);

Pull Zone

List Pull Zones

$baseApi->listPullZones(
    query: [
        'page' => 0,
        'perPage' => 1000,
        'search' => 'bunny',
        'includeCertificate' => false,
    ],
);

Note

  • The key search is currently not functional.

Add Pull Zone

$baseApi->addPullZone(
    body: [
        'OriginUrl' => 'https://my-bucket-2.service.com',
        'AllowedReferrers' => [],
        'BlockedReferrers' => [],
        'BlockedIps' => [],
        'EnableGeoZoneUS' => true,
        'EnableGeoZoneEU' => true,
        'EnableGeoZoneASIA' => true,
        'EnableGeoZoneSA' => true,
        'EnableGeoZoneAF' => true,
        'BlockRootPathAccess' => false,
        'BlockPostRequests' => false,
        'EnableQueryStringOrdering' => true,
        'EnableWebpVary' => false,
        'EnableAvifVary' => false,
        'EnableMobileVary' => false,
        'EnableCountryCodeVary' => false,
        'EnableHostnameVary' => false,
        'EnableCacheSlice' => false,
        'ZoneSecurityEnabled' => false,
        'ZoneSecurityIncludeHashRemoteIP' => false,
        'IgnoreQueryStrings' => true,
        'MonthlyBandwidthLimit' => 0,
        'AccessControlOriginHeaderExtensions' => [],
        'EnableAccessControlOriginHeader' => true,
        'DisableCookies' => true,
        'BudgetRedirectedCountries' => [],
        'BlockedCountries' => [],
        'CacheControlMaxAgeOverride' => -1,
        'CacheControlPublicMaxAgeOverride' => -1,
        'CacheControlBrowserMaxAgeOverride' => 157784760,
        'AddHostHeader' => false,
        'AddCanonicalHeader' => false,
        'EnableLogging' => true,
        'LoggingIPAnonymizationEnabled' => true,
        'PermaCacheStorageZoneId' => 0,
        'AWSSigningEnabled' => false,
        'AWSSigningKey' => null,
        'AWSSigningRegionName' => null,
        'AWSSigningSecret' => null,
        'EnableOriginShield' => false,
        'OriginShieldZoneCode' => 'FR',
        'EnableTLS1' => true,
        'EnableTLS1_1' => true,
        'CacheErrorResponses' => false,
        'VerifyOriginSSL' => false,
        'LogForwardingEnabled' => false,
        'LogForwardingHostname' => null,
        'LogForwardingPort' => 0,
        'LogForwardingToken' => null,
        'LogForwardingProtocol' => 0,
        'LoggingSaveToStorage' => false,
        'LoggingStorageZoneId' => 0,
        'FollowRedirects' => false,
        'ConnectionLimitPerIPCount' => 0,
        'RequestLimit' => 0,
        'LimitRateAfter' => 0,
        'LimitRatePerSecond' => 0,
        'BurstSize' => 0,
        'WAFEnabled' => false,
        'WAFDisabledRuleGroups' => [],
        'WAFDisabledRules' => [],
        'WAFEnableRequestHeaderLogging' => false,
        'WAFRequestHeaderIgnores' => [],
        'ErrorPageEnableCustomCode' => false,
        'ErrorPageCustomCode' => null,
        'ErrorPageEnableStatuspageWidget' => false,
        'ErrorPageStatuspageCode' => null,
        'ErrorPageWhitelabel' => false,
        'OptimizerEnabled' => false,
        'OptimizerDesktopMaxWidth' => 1600,
        'OptimizerMobileMaxWidth' => 800,
        'OptimizerImageQuality' => 85,
        'OptimizerMobileImageQuality' => 70,
        'OptimizerEnableWebP' => true,
        'OptimizerEnableManipulationEngine' => true,
        'OptimizerMinifyCSS' => true,
        'OptimizerMinifyJavaScript' => true,
        'OptimizerWatermarkEnabled' => true,
        'OptimizerWatermarkUrl' => '',
        'OptimizerWatermarkPosition' => 0,
        'OptimizerWatermarkOffset' => 3,
        'OptimizerWatermarkMinImageSize' => 300,
        'OptimizerAutomaticOptimizationEnabled' => true,
        'OptimizerClasses' => [],
        'OptimizerForceClasses' => false,
        'Type' => 0,
        'OriginRetries' => 0,
        'OriginConnectTimeout' => 10,
        'OriginResponseTimeout' => 60,
        'UseStaleWhileUpdating' => false,
        'UseStaleWhileOffline' => false,
        'OriginRetry5XXResponses' => false,
        'OriginRetryConnectionTimeout' => true,
        'OriginRetryResponseTimeout' => true,
        'OriginRetryDelay' => 0,
        'DnsOriginPort' => 0,
        'DnsOriginScheme' => '',
        'QueryStringVaryParameters' => [],
        'OriginShieldEnableConcurrencyLimit' => false,
        'OriginShieldMaxConcurrentRequests' => 5000,
        'EnableCookieVary' => false,
        'CookieVaryParameters' => [],
        'EnableSafeHop' => false,
        'OriginShieldQueueMaxWaitTime' => 30,
        'UseBackgroundUpdate' => false,
        'OriginShieldMaxQueuedRequests' => 5000,
        'UseBackgroundUpdate' => true,
        'EnableAutoSSL' => false,
        'LogAnonymizationType' => 0,
        'StorageZoneId' => 0,
        'EdgeScriptId' => 0,
        'OriginType' => 0,
        'MagicContainersAppId' => '',
        'LogFormat' => 0,
        'LogForwardingFormat' => 0,
        'ShieldDDosProtectionType' => 1,
        'ShieldDDosProtectionEnabled' => false,
        'OriginHostHeader' => '',
        'EnableSmartCache' => false,
        'EnableRequestCoalescing' => false,
        'RequestCoalescingTimeout' => 30,
        'DisableLetsEncrypt' => false,
        'EnableBunnyImageAi' => false,
        'BunnyAiImageBlueprints' => [],
        'PreloadingScreenEnabled' => false,
        'PreloadingScreenCode' => '',
        'PreloadingScreenLogoUrl' => null,
        'PreloadingScreenTheme' => 0,
        'PreloadingScreenCodeEnabled' => false,
        'PreloadingScreenDelay' => 700,
        'RoutingFilters' => [],
        'Name' => 'New Pull Zone',
    ],
);

Note

  • The key Type has the following possible values:
    • 0 = Premium
    • 1 = Volume
  • The key OriginType has the following possible values:
    • 0 = OriginUrl
    • 1 = DnsAccelerate
    • 2 = StorageZone
    • 3 = LoadBalancer
    • 4 = EdgeScript
    • 5 = MagicContainers
    • 6 = PushZone
  • The key LogFormat has the following possible values:
    • 0 = Plain
    • 1 = JSON
  • The key LogForwardingFormat has the following possible values:
    • 0 = Plain
    • 1 = JSON
  • The key ShieldDDosProtectionType has the following possible values:
    • 0 = DetectOnly
    • 1 = ActiveStandard
    • 2 = ActiveAggressive
  • The key LogAnonymizationType has the following possible values:
    • 0 = Remove one octet
    • 1 = Drop IP
  • The key LogForwardingProtocol has the following possible values:
    • 0 = UDP
    • 1 = TCP
    • 2 = TCPEncrypted
    • 3 = DataDog
  • The key OptimizerWatermarkPosition has the following possible values:
    • 0 = BottomLeft
    • 1 = BottomRight
    • 2 = TopLeft
    • 4 = Center
    • 5 = CenterStretch
  • The keys CacheControlBrowserMaxAgeOverride and CacheControlBrowserMaxAgeOverride accept any values in seconds. The Bunny dashboard will show the value Match Server Cache Expiration but the value updated through the API will be honored.
  • The key OriginShieldZoneCode accepts the 2-digit code FR (France, Paris) or IL (Illinois, Chicago).
  • The WAF related settings are not implemented yet. This feature is currently being worked on and does not have an ETA. It is advised not to update these values until the feature is implemented, therefore these options are removed from the example above.

Get Pull Zone

$baseApi->getPullZone(
    id: 1,
    query: [
        'includeCertificate' => false,
    ],
);

Update Pull Zone

$baseApi->updatePullZone(
    id: 1,
    body: [
        'OriginUrl' => 'https://my-bucket-2.service.com',
        'AllowedReferrers' => [],
        'BlockedReferrers' => [],
        'BlockedIps' => [],
        'EnableGeoZoneUS' => true,
        'EnableGeoZoneEU' => true,
        'EnableGeoZoneASIA' => true,
        'EnableGeoZoneSA' => true,
        'EnableGeoZoneAF' => true,
        'BlockRootPathAccess' => false,
        'BlockPostRequests' => false,
        'EnableQueryStringOrdering' => true,
        'EnableWebpVary' => false,
        'EnableAvifVary' => false,
        'EnableMobileVary' => false,
        'EnableCountryCodeVary' => false,
        'EnableHostnameVary' => false,
        'EnableCacheSlice' => false,
        'ZoneSecurityEnabled' => false,
        'ZoneSecurityIncludeHashRemoteIP' => false,
        'IgnoreQueryStrings' => true,
        'MonthlyBandwidthLimit' => 0,
        'AccessControlOriginHeaderExtensions' => [],
        'EnableAccessControlOriginHeader' => true,
        'DisableCookies' => true,
        'BudgetRedirectedCountries' => [],
        'BlockedCountries' => [],
        'CacheControlMaxAgeOverride' => -1,
        'CacheControlPublicMaxAgeOverride' => -1,
        'CacheControlBrowserMaxAgeOverride' => 157784760,
        'AddHostHeader' => false,
        'AddCanonicalHeader' => false,
        'EnableLogging' => true,
        'LoggingIPAnonymizationEnabled' => true,
        'PermaCacheStorageZoneId' => 0,
        'AWSSigningEnabled' => false,
        'AWSSigningKey' => null,
        'AWSSigningRegionName' => null,
        'AWSSigningSecret' => null,
        'EnableOriginShield' => false,
        'OriginShieldZoneCode' => 'FR',
        'EnableTLS1' => true,
        'EnableTLS1_1' => true,
        'CacheErrorResponses' => false,
        'VerifyOriginSSL' => false,
        'LogForwardingEnabled' => false,
        'LogForwardingHostname' => null,
        'LogForwardingPort' => 0,
        'LogForwardingToken' => null,
        'LogForwardingProtocol' => 0,
        'LoggingSaveToStorage' => false,
        'LoggingStorageZoneId' => 0,
        'FollowRedirects' => false,
        'ConnectionLimitPerIPCount' => 0,
        'RequestLimit' => 0,
        'LimitRateAfter' => 0,
        'LimitRatePerSecond' => 0,
        'BurstSize' => 0,
        'WAFEnabled' => false,
        'WAFDisabledRuleGroups' => [],
        'WAFDisabledRules' => [],
        'WAFEnableRequestHeaderLogging' => false,
        'WAFRequestHeaderIgnores' => [],
        'ErrorPageEnableCustomCode' => false,
        'ErrorPageCustomCode' => null,
        'ErrorPageEnableStatuspageWidget' => false,
        'ErrorPageStatuspageCode' => null,
        'ErrorPageWhitelabel' => false,
        'OptimizerEnabled' => false,
        'OptimizerDesktopMaxWidth' => 1600,
        'OptimizerMobileMaxWidth' => 800,
        'OptimizerImageQuality' => 85,
        'OptimizerMobileImageQuality' => 70,
        'OptimizerEnableWebP' => true,
        'OptimizerEnableManipulationEngine' => true,
        'OptimizerMinifyCSS' => true,
        'OptimizerMinifyJavaScript' => true,
        'OptimizerWatermarkEnabled' => true,
        'OptimizerWatermarkUrl' => '',
        'OptimizerWatermarkPosition' => 0,
        'OptimizerWatermarkOffset' => 3,
        'OptimizerWatermarkMinImageSize' => 300,
        'OptimizerAutomaticOptimizationEnabled' => true,
        'OptimizerClasses' => [],
        'OptimizerForceClasses' => false,
        'Type' => 0,
        'OriginRetries' => 0,
        'OriginConnectTimeout' => 10,
        'OriginResponseTimeout' => 60,
        'UseStaleWhileUpdating' => false,
        'UseStaleWhileOffline' => false,
        'OriginRetry5XXResponses' => false,
        'OriginRetryConnectionTimeout' => true,
        'OriginRetryResponseTimeout' => true,
        'OriginRetryDelay' => 0,
        'DnsOriginPort' => 0,
        'DnsOriginScheme' => '',
        'QueryStringVaryParameters' => [],
        'OriginShieldEnableConcurrencyLimit' => false,
        'OriginShieldMaxConcurrentRequests' => 5000,
        'EnableCookieVary' => false,
        'CookieVaryParameters' => [],
        'EnableSafeHop' => false,
        'OriginShieldQueueMaxWaitTime' => 30,
        'UseBackgroundUpdate' => false,
        'OriginShieldMaxQueuedRequests' => 5000,
        'UseBackgroundUpdate' => true,
        'EnableAutoSSL' => false,
        'LogAnonymizationType' => 0,
        'StorageZoneId' => 0,
        'EdgeScriptId' => 0,
        'OriginType' => 0,
        'MagicContainersAppId' => '',
        'LogFormat' => 0,
        'LogForwardingFormat' => 0,
        'ShieldDDosProtectionType' => 1,
        'ShieldDDosProtectionEnabled' => false,
        'OriginHostHeader' => '',
        'EnableSmartCache' => false,
        'EnableRequestCoalescing' => false,
        'RequestCoalescingTimeout' => 30,
        'DisableLetsEncrypt' => false,
        'EnableBunnyImageAi' => false,
        'BunnyAiImageBlueprints' => [],
        'PreloadingScreenEnabled' => false,
        'PreloadingScreenCode' => '',
        'PreloadingScreenLogoUrl' => null,
        'PreloadingScreenTheme' => 0,
        'PreloadingScreenCodeEnabled' => false,
        'PreloadingScreenDelay' => 700,
        'RoutingFilters' => [],
    ],
);

Note

  • The key Type has the following possible values:
    • 0 = Premium
    • 1 = Volume
  • The key OriginType has the following possible values:
    • 0 = OriginUrl
    • 1 = DnsAccelerate
    • 2 = StorageZone
    • 3 = LoadBalancer
    • 4 = EdgeScript
    • 5 = MagicContainers
    • 6 = PushZone
  • The key LogFormat has the following possible values:
    • 0 = Plain
    • 1 = JSON
  • The key LogForwardingFormat has the following possible values:
    • 0 = Plain
    • 1 = JSON
  • The key ShieldDDosProtectionType has the following possible values:
    • 0 = DetectOnly
    • 1 = ActiveStandard
    • 2 = ActiveAggressive
  • The key LogAnonymizationType has the following possible values:
    • 0 = Remove one octet
    • 1 = Drop IP
  • The key LogForwardingProtocol has the following possible values:
    • 0 = UDP
    • 1 = TCP
    • 2 = TCPEncrypted
    • 3 = DataDog
  • The key OptimizerWatermarkPosition has the following possible values:
    • 0 = BottomLeft
    • 1 = BottomRight
    • 2 = TopLeft
    • 4 = Center
    • 5 = CenterStretch
  • The keys CacheControlBrowserMaxAgeOverride and CacheControlBrowserMaxAgeOverride accept any values in seconds. The Bunny dashboard will show the value Match Server Cache Expiration but the value updated through the API will be honored.
  • The key OriginShieldZoneCode accepts the 2-digit code FR (France, Paris) or IL (Illinois, Chicago).
  • The WAF related settings are not implemented yet. This feature is currently being worked on and does not have an ETA. It is advised not to update these values until the feature is implemented, therefore these options are removed from the example above.

Delete Pull Zone

$baseApi->deletePullZone(
    id: 1,
);

Add Edge Rule

$baseApi->addEdgeRule(
    pullZoneId: 1,
    body: [
        'ActionType' => 4,
        'ActionParameter1' => '',
        'ActionParameter2' => '',
        'Triggers' => [
            [
                'Type' => 0,
                'PatternMatches' => [
                    'https://example.b-cdn.net/images/*',
                    'https://example.b-cdn.net/videos/*',
                ]
                'PatternMatchingType' => 0,
                'Parameter1' => '',
            ],
        ],
        'TriggerMatchingType' => 0,
        'Description' => '',
        'Enabled' => true
    ],
);

Note

  • The key ActionType has the following possible values:
    • 0 = Force SSL
    • 1 = Redirect To URL
    • 2 = Change Origin URL
    • 3 = Override Cache Time
    • 4 = Block Request
    • 5 = Set Response header
    • 6 = Set Request Header
    • 7 = Force Download
    • 8 = Disable Token Authentication
    • 9 = Enable Token Authentication
    • 10 = Override Cache Time Public
    • 11 = Ignore Query String (Cache Vary)
    • 12 = Disable Bunny Optimizer
    • 13 = Force Compression
    • 14 = Set Status Code
    • 15 = Bypass Perma-Cache
    • 16 = Override Browser Cache Time
    • 17 = Origin Storage
    • 18 = Set Network Rate Limit
    • 19 = Set Connection Limit
    • 20 = Set Requests Per Second Limit
  • The key Type in a Trigger object has the following possible values:
    • 0 = URL
    • 1 = Request Header
    • 2 = Response Header
    • 3 = File/URL Extension
    • 4 = Country Code (2 letter)
    • 5 = Remote IP
    • 6 = Query String
    • 7 = Random Chance (%)
    • 8 = Status Code
    • 9 = Request method
    • 10 = Cookie Value
    • 11 = Country State Code
  • The key TriggerMatchingType has the following possible values:
    • 0 = Match Any
    • 1 = Match All
    • 2 = Match None

Update Edge Rule

$baseApi->updateEdgeRule(
    pullZoneId: 1,
    body: [
        'Guid' => 'c71d9594-3bc6-4639-9896-ba3e96217587',
        'Triggers' => [
            [
                'Type' => 7,
                'PatternMatches' => ['75']
            ],
        ],
    ],
);

Note

  • The keys Guid and Triggers in the body are required parameters when updating an edge rule.

Set Edge Rule Enabled

$baseApi->setEdgeRuleEnabled(
    pullZoneId: 1,
    edgeRuleId: 'c71d9594-3bc6-4639-9896-ba3e96217587',
    body: [
        'Id' => 1,
        'Value' => true,
    ],
);

Note

  • The key Id in the body denotes the pull zone ID (the same as the first argument) and is (for some reason) a required parameter.

Delete Edge Rule

$baseApi->deleteEdgeRule(
    pullZoneId: 1,
    edgeRuleId: 'c71d9594-3bc6-4639-9896-ba3e96217587',
);

Set Zone Security Enabled

$baseApi->setZoneSecurityEnabled(
    Id: 1,
    Value: true
);

Note

  • This endpoint corresponds to toggling the Enable Token Authentication switch in the Token Authentication > Security section of your pull zone.

Warning

  • This endpoint is currently not documented in the API specifications.

Set Zone Security Include Hash Remote IP Enabled

$baseApi->setZoneSecurityIncludeHashRemoteIPEnabled(
    Id: 1,
    Value: true
);

Note

  • This endpoint corresponds to toggling the Token IP Validation switch in the Token Authentication > Security section of your pull zone.

Warning

  • This endpoint is currently not documented in the API specifications.

Get Origin Shield Queue Statistics

$baseApi->getOriginShieldQueueStatistics(
    pullZoneId: 1,
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
        'hourly' => false,
    ],
);

Get SafeHop Statistics

$baseApi->getSafeHopStatistics(
    pullZoneId: 1,
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
        'hourly' => false,
    ],
);

Get Optimizer Statistics

$baseApi->getOptimizerStatistics(
    pullZoneId: 1,
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
        'hourly' => false,
    ],
);

Get WAF Statistics

$baseApi->getWafStatistics(
    pullZoneId: 1,
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
        'hourly' => false,
    ],
);

Warning

  • This endpoint is currently not documented in the API specifications.

Load Free Certificate

$baseApi->loadFreeCertificate(
    query: [
        'hostname' => 'cdn.example.com',
    ],
);

Purge Cache (by tag)

$baseApi->purgePullZoneCache(
    id: 1,
    body: [
        'CacheTag' => 'mytag-region-*',
    ],
);

Check Pull Zone Availability

$baseApi->checkPullZoneAvailability(
    body: [
        'Name' => 'test',
    ],
);

Add Certificate

$baseApi->addCertificate(
    id: 1,
    body: [
        'Hostname' => 'cdn.example.com',
        'Certificate' => 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk5ldmVyIGdvbm5hIGdpdmUgeW91IHVwLgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t',
        'CertificateKey' => 'LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpOZXZlciBnb25uYSBsZXQgeW91IGRvd24uCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t',
    ],
);

Note

  • The keys Certificate and CertificateKey require the file contents to be sent as base64 encoded strings.

Remove Certificate

$baseApi->removeCertificate(
    id: 1,
    body: [
        'Hostname' => 'cdn.example.com',
    ],
);

Add Custom Hostname

$baseApi->addCustomHostname(
    id: 1,
    body: [
        'Hostname' => 'cdn.example.com',
    ],
);

Remove Custom Hostname

$baseApi->removeCustomHostname(
    id: 1,
    body: [
        'Hostname' => 'cdn.example.com',
    ],
);

Set Force SSL

$baseApi->setForceSsl(
    id: 1,
    body: [
        'Hostname' => 'cdn.example.com',
        'ForceSSL' => true,
    ],
);

Reset Token Key

$baseApi->resetPullZoneTokenKey(
    id: 1,
);

Add Allowed Referer

$baseApi->addPullZoneAllowedReferer(
    id: 1,
    body: [
        'Hostname' => '*.example.com,*.example.org',
    ],
);

Note

  • The key Hostname allows multiple values through comma separated values.

Remove Allowed Referer

$baseApi->removePullZoneAllowedReferer(
    id: 1,
    body: [
        'Hostname' => '*.example.com',
    ],
);

Note

  • The key Hostname does not allow multiple values.

Add Blocked Referer

$baseApi->addPullZoneBlockedReferer(
    id: 1,
    body: [
        'Hostname' => '*.evil.org',
    ],
);

Note

  • The key Hostname does not allow multiple values.

Remove Blocked Referer

$baseApi->removePullZoneBlockedReferer(
    id: 1,
    body: [
        'Hostname' => '*.evil.org',
    ],
);

Add Blocked IP

$baseApi->addPullZoneBlockedIp(
    id: 1,
    body: [
        'BlockedIp' => '12.345.67.89',
    ],
);

Remove Blocked IP

$baseApi->removePullZoneBlockedIp(
    id: 1,
    body: [
        'BlockedIp' => '12.345.67.89',
    ],
);

Purge

Purge URL

$baseApi->purgeUrl(
    query: [
        'url' => 'https://example.b-cdn.net/images/*',
        'async' => false,
    ],
);

Purge URL (by header)

$baseApi->purgeUrlByHeader(
    query: [
        'url' => 'https://example.b-cdn.net/images/*',
        'headerName' => '',
        'headerValue' => '',
        'async' => false,
    ],
);
$baseApi->getGlobalSearch(
    query: [
        'search' => 'bunny',
        'from' => 0,
        'size' => 20,
    ],
);

Warning

  • It is unclear from the current API specifications what you can actually search for with this endpoint.

Statistics

Get Statistics (traffic, cache hit & bandwidth)

$baseApi->getStatistics(
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
        'pullZone' => -1,
        'serverZoneId' => -1,
        'loadErrors' => false,
        'hourly' => false,
    ],
);

Storage Zone

List Storage Zones

$baseApi->listStorageZones(
    query: [
        'page' => 0,
        'perPage' => 1000,
        'search' => 'bunny',
        'includeDeleted' => 1000,
    ],
);

Note

  • The key search is currently not functional.

Add Storage Zone

$baseApi->addStorageZone(
    body: [
        'OriginUrl' => '',
        'Name' => 'Test',
        'Region' => 'DE',
        'ReplicationRegions' => '',
        'ZoneTier' => 0,
    ],
);

Note

  • The key OriginUrl allows you to specify a backup data source, in case the file does not exist on the Storage Zone. So for example, you would request /image.png. Assuming image.png doesn't exist on the storage zone, the system will try to proxy and fetch it from the OriginUrl instead. You can omit it unless needed.
  • The key ZoneTier has the following possible values (undocumented):
    • 0 = Standard = HDD
    • 1 = Edge = SSD
  • The key Region has the following possible values:
    • DE = Falkenstein / Frankfurt (Germany) | HDD + SSD
    • UK = London (United Kingdom) | HDD
    • SE = Norway (Stockholm) | HDD
    • NY = New York (United States) | HDD
    • LA = Los Angeles (United States) | HDD
    • SG = Singapore (Singapore) | HDD
    • SYD = Sydney (Oceania) | HDD
    • BR = Sao Paolo (Brazil) | HDD
    • JH = Johannesburg (Africa) | HDD
  • The key ReplicationRegions has the following possible values:
    • DE = Frankfurt (Germany) | SSD
    • UK = London (United Kingdom) | HDD + SSD
    • SE = Norway (Stockholm) | HDD + SSD
    • CZ = Prague (Czech Republic) | SSD
    • ES = Madrid (Spain) | SSD
    • NY = New York (United States East) | HDD + SSD
    • LA = Los Angeles (United States West) | HDD + SSD
    • WA = Seattle (United States West) | SSD
    • MI = Miami (United States East) | SSD
    • SG = Singapore (Singapore) | HDD + SSD
    • HK = Hong Kong (SAR of China) | SSD
    • JP = Tokyo (Japan) | SSD
    • SYD = Sydney (Oceania) | HDD + SSD
    • BR = Sao Paolo (Brazil) | HDD + SSD
    • JH = Johannesburg (Africa) | HDD + SSD

Check Storage Zone Availability

$baseApi->checkStorageZoneAvailability(
    body: [
        'Name' => 'Test',
    ],
);

Get Storage Zone

$baseApi->getStorageZone(
    id: 1,
);

Get Storage Zone

$baseApi->getStorageZone(
    id: 1,
);

Update Storage Zone

$baseApi->updateStorageZone(
    id: 1,
    body: [
        'ReplicationZones' => '',
        'OriginUrl' => '',
        'Custom404FilePath' => 'my-custom-404.html',
        'Rewrite404To200' => false,
    ],
);

Note

  • The key OriginUrl allows you to specify a backup data source, in case the file does not exist on the Storage Zone. So for example, you would request /image.png. Assuming image.png doesn't exist on the storage zone, the system will try to proxy and fetch it from the OriginUrl instead. You can omit it unless needed.
  • The key ReplicationZones has the following possible values:
    • DE = Frankfurt (Germany) | SSD
    • UK = London (United Kingdom) | HDD + SSD
    • SE = Norway (Stockholm) | HDD + SSD
    • CZ = Prague (Czech Republic) | SSD
    • ES = Madrid (Spain) | SSD
    • NY = New York (United States East) | HDD + SSD
    • LA = Los Angeles (United States West) | HDD + SSD
    • WA = Seattle (United States West) | SSD
    • MI = Miami (United States East) | SSD
    • SG = Singapore (Singapore) | HDD + SSD
    • HK = Hong Kong (SAR of China) | SSD
    • JP = Tokyo (Japan) | SSD
    • SYD = Sydney (Oceania) | HDD + SSD
    • BR = Sao Paolo (Brazil) | HDD + SSD
    • JH = Johannesburg (Africa) | HDD + SSD

Delete Storage Zone

$baseApi->deleteStorageZone(
    id: 1,
);

Get Storage Zone Statistics

$baseApi->getStorageZoneStatistics(
    id: 1,
    query: [
        'dateFrom' => 'm-d-Y',
        'dateTo' => 'm-d-Y',
    ],
);

Get Storage Zone Connections

$baseApi->getStorageZoneConnections(
    id: 1,
);

Reset Password

$baseApi->resetStorageZonePassword(
    id: 1,
);

Reset Read-Only Password

$baseApi->resetStorageZoneReadOnlyPassword(
    query: [
        'id' => 1,
    ],
);

User

Get Home Feed

$baseApi->getHomeFeed();

Get User Details

$baseApi->getUserDetails();

Update User Details

$baseApi->updateUserDetails(
    body: [
        'FirstName' => 'John',
        'Email' => 'john.doe@example.com',
        'BillingEmail' => 'john.doe@example.com',
        'LastName' => 'Doe',
        'StreetAddress' => '1985 Robinson Court',
        'City' => 'Windom',
        'ZipCode' => '75492',
        'Country' => 'US',
        'CompanyName' => '',
        'VATNumber' => '',
        'ReceiveNotificationEmails' => true,
        'ReceivePromotionalEmails' => false,
        'Password' => '1234Abcd',
        'OldPassword' => 'Abcd1234',
    ],
);

Resend Email Confirmation

$baseApi->resendEmailConfirmation();

Reset API Key

$baseApi->resetUserApiKey();

List Close Account Reasons

$baseApi->listCloseAccountReasons();

Close Account

$baseApi->closeAccount(
    body: [
        'Password' => 'Abcd1234',
        'Reason' => 'No longer needed.',
    ],
);

Get DPA Details

$baseApi->getDpaDetails();

Accept DPA

$baseApi->acceptDpa();

Get DPA Details (HTML)

$baseApi->getDpaDetailsHtml();

List Notifications

$baseApi->listNotifications();

Set Notifications Opened

$baseApi->setNotificationsOpened();

Get Marketing Details

$baseApi->getMarketingDetails();

Get What's New Items

$baseApi->getWhatsNewItems();

Reset What's New

$baseApi->resetWhatsNew();

Generate 2FA Verification

$baseApi->generateTwoFactorAuthenticationVerification();

Disable 2FA

$baseApi->disableTwoFactorAuthentication(
    body: [
        'Password' => 'LoremIpsumDolor',
    ],
);

Enable 2FA

$baseApi->enableTwoFactorAuthentication(
    body: [
        'SecretValidator' => '',
        'Secret' => '',
        'TestPin' => '123456',
    ],
);

Verify 2FA Code

$baseApi->verifyTwoFactorAuthenticationCode(
    body: [
        'SecretValidator' => '',
        'Secret' => '',
        'TestPin' => '123456',
    ],
);

Reference