Cloudflare-API

 view release on metacpan or  search on metacpan

doc/cloudflare-api.md  view on Meta::CPAN

# Introduction {#introduction}

Want to list your R2 buckets, inspect a Worker, or create a D1 database from a Perl script? `Cloudflare::API` gives you a small client for those everyday Cloudflare management tasks. It uses `HTTP::API::Core` for the HTTPS transport, authentication h...

You can call the module from Perl or use the accompanying `cloudflare-api` command when a shell is more convenient. Both talk to Cloudflare's management API. Neither builds a Worker project or runs npm. The command can use a Wrangler login when you r...

If you only need a quick look, the next example shows the whole idea. The later sections explain credentials, resource methods, uploads, responses, and command-line options. A module-by-module reference is near the end.

``` perl
use strict;
use warnings;
use Cloudflare::API;

my $api_or=Cloudflare::API->new();
my $buckets_ar=$api_or->r2()->list_buckets();
my $scripts_ar=$api_or->workers()->list_scripts();
```

With `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` set, the client supplies the account path and bearer token. List methods follow Cloudflare's pages and return a flat array reference. Other JSON methods normally return the decoded `result`.

!!! note

    The distribution requires Perl 5.10 or later, `HTTP::API::Core` 1.08 or
    later, and Perl HTTPS support through `IO::Socket::SSL`. Install it with
    a CPAN client in the usual way.

# Credentials and account context {#credentials}

Create an API token in the Cloudflare dashboard with only the permissions and account or zone access your script needs. Cloudflare offers user tokens and account tokens; the endpoint and your account permissions determine which is appropriate. Copy t...

``` sh
# Load CLOUDFLARE_API_TOKEN from your secret manager first.
export CLOUDFLARE_ACCOUNT_ID='your-account-id'
cloudflare-api --resource r2 --action list_buckets
```

The account ID above is a placeholder. Load the token through your secret manager so it does not enter a repository or a pasted command. The module also accepts explicit `token` and `account_id` constructor options:

``` perl
my $api_or=Cloudflare::API->new(
    token      => $ENV{'CLOUDFLARE_API_TOKEN'},
    account_id => $ENV{'CLOUDFLARE_ACCOUNT_ID'},
    timeout    => 30
);
```

You can omit `account_id` for account and zone lookup, but account-scoped methods need it. The command has `--account-id` to choose another account while continuing to read the token from the environment.

!!! warning

    An API token is a credential, even when it is short lived. Do not commit
    it, paste it into command-line arguments, print it in logs, or include
    it in error reports. Use a narrowly scoped token; a token that can edit
    a resource can change or delete it through the relevant methods.

If you have logged into Wrangler locally, the command can ask Wrangler for a token for each invocation. Wrangler refreshes an expired OAuth token before returning it:

``` sh
cloudflare-api --auth=wrangler --resource workers --action list_scripts
```

For an account-scoped named method, `--auth=wrangler` also uses `wrangler whoami --json` to obtain the account ID when the login has exactly one available account. If it has several, select one with `--account-id` or `CLOUDFLARE_ACCOUNT_ID`; either v...

!!! tip

    For unattended scripts, use a dedicated, limited API token supplied by a
    secret manager. The Wrangler shortcut is best suited to an interactive
    session you control.

# A first Perl script {#perl-synopsis}

Let's list two resources without changing anything. Resource accessors are named for the Cloudflare service, and their methods follow the action you want to perform:

``` perl
use strict;
use warnings;
use Cloudflare::API;

my $api_or=Cloudflare::API->new();
my $zones_ar=$api_or->zones()->list(status => 'active');
my $namespaces_ar=$api_or->kv()->list_namespaces(per_page => 20);

foreach my $zone_hr (@$zones_ar) {
    print $zone_hr->{'name'}, "\n";
}
```

zones()->list() is not account-scoped; kv()->list_namespaces() is. List methods accept Cloudflare query fields as named arguments, follow every available page, and return a flat array reference of items.

To create something, pass Cloudflare's JSON request body as a hash reference. Here are two independent examples:

``` perl
my $bucket_hr=$api_or->r2()->create_bucket({
    name => 'my-app-assets'
});

my $database_hr=$api_or->d1()->create_database({
    name => 'my-app-data'
});
```

!!! caution

    These calls create real Cloudflare resources. The module does not check
    whether a name already exists, make writes idempotent, or roll back
    later calls if a script fails.

# Exploring the resource API {#resource-api}

The client has accessors for accounts(), zones(), workers(), r2(), kv(), d1(), queues(), hyperdrive(), and secrets_store(). Each returns a small resource object tied to the same client and token. The examples below show representative operations rath...

## Lists, detail, and changes {#read-and-write}

Most resources offer a familiar list, get, create, update, and delete pattern. For example, you can list R2 buckets, get one by name, then update or delete it using that name. Queues, Hyperdrive configurations, and Secrets Store resources follow the ...

``` perl
my $bucket_hr=$api_or->r2()->get_bucket('my-app-assets');
my $queue_hr=$api_or->queues()->create_queue({ name => 'jobs' });
my $config_ar=$api_or->hyperdrive()->list_configs();
```

Accounts and zones are useful starting points when you do not yet know an ID:

doc/cloudflare-api.md  view on Meta::CPAN


``` perl
my $page_or=$api_or->r2()->list_buckets_page(per_page => 100);
while (my $bucket_hr=$page_or->next()) {
    print $bucket_hr->{'name'}, "\n";
}
```

The corresponding \_page_response() method makes exactly one request and returns the complete decoded Cloudflare response hash. Use it when you need `result_info`, page boundaries, or other response fields:

``` perl
my $page_hr=$api_or->r2()->list_buckets_page_response(per_page => 100);
my $buckets_ar=$page_hr->{'result'}{'buckets'};
```

The exact response and pagination fields depend on the endpoint. A supplied `page` or `cursor` selects the starting point for a list method or paginator. `full_response` is unavailable for list method families; use \_page_response() instead. The comm...

An HTTP or transport failure is thrown as an `HTTP::API::Core::Error`. A successful HTTP response whose decoded Cloudflare response says `success: false` is thrown as `Cloudflare::API::Error`; it retains errors(), messages(), and the underlying respo...

``` perl
my $result_hr=eval { $api_or->r2()->get_bucket('my-app-assets') };
if (my $error=$@) {
    if (ref($error) && $error->isa('Cloudflare::API::Error')) {
        warn "Cloudflare rejected the request: $error\n";
    }
    else {
        die $error;
    }
}
```

!!! note

    A missing account ID or invalid local argument may also raise an
    ordinary Perl exception before any request is made. Keep tokens and
    secret request bodies out of exception logs.

# When there is no named method {#lower-level-api}

The named methods cover a useful part of Cloudflare's API, not every endpoint. Use request() for a JSON endpoint that does not yet have a wrapper. It accepts an HTTP method, a path relative to the Cloudflare API root, and `HTTP::API::Core` request op...

``` perl
my $accounts_ar=$api_or->request('GET', '/accounts',
    query => { per_page => 20 }
);
my $decoded_hr=$api_or->request_full('GET', '/accounts');
my $response_or=$api_or->response('GET', '/accounts');
```

request() unwraps `result`, request_full() keeps the complete decoded Cloudflare response, and response() returns the `HTTP::API::Core::Response` object. Use response() for non-JSON content or when you need response details that the JSON helpers do n...

!!! important

    Paths must start with one slash and cannot be absolute URLs, so a
    caller-supplied path cannot send the bearer token to another host. If
    you put a dynamic value in a low-level path, percent-encode that segment
    yourself. Named resource methods encode their own path segments.

# Using the command-line script {#command-line}

`cloudflare-api` is useful for a quick lookup or a shell script that already has credentials in its environment. Choose a resource and action for a named method. Output is pretty JSON unless you ask for `dumper`:

``` sh
cloudflare-api --resource zones --action list --param status=active
cloudflare-api --resource r2 --action list_buckets --full-response
cloudflare-api --resource zones --action list --output dumper
```

A `--param` passes a named string argument, usually a list filter. `--arg` passes a positional string argument, in the order given. For a method expecting a JSON body, use a typed argument rather than a string:

``` sh
cloudflare-api --resource kv --action create_namespace \
    --arg-json '{"title":"my-app-cache"}'
cloudflare-api --resource workers --action upload_assets \
    --arg my-app --arg dist/site --param prefix=/docs
```

For selected files, give the Worker name with `--arg`, then combine repeatable `--asset FILE`, `--asset-list-json FILE`, and `--asset-list-text FILE`. Use `--asset-list-stdin` once to read one filename per line from standard input. Text lists ignore ...

``` sh
cloudflare-api --resource workers --action upload_assets \
    --arg my-app --asset dist/index.html --asset-list-text images.txt \
    --param prefix=/docs
```

Typed positional forms include `--arg-bool`, `--arg-array`, `--arg-hash`, `--arg-json`, and `--arg-json-file`. Named forms include `--param-bool`, `--param-json`, and `--param-json-file`. The JSON file forms are handy for longer bodies; for example, ...

The command deliberately makes one request for a list action unless `--paginate` is supplied. With `--paginate`, it returns an array of page results, preserving each page boundary. Without `--max-pages`, it follows every page Cloudflare reports:

``` sh
cloudflare-api --resource kv --action list_namespaces \
    --paginate --per-page 20 --max-pages 2 --full-response
```

The lower-level form uses `--method` and `--path` instead of a resource and action:

``` sh
cloudflare-api --method GET --path /accounts --full-response
```

Use `--help` for a short reminder, `--man` for the complete option reference, or `--version` for the installed version. The command also has `--account-id` and `--output json|dumper`.

!!! warning

    The `--arg-dumper-file` and `--param-dumper-file` options evaluate the
    file as Perl code. Use them only with files you trust; prefer JSON for
    data from elsewhere. `--dump-opt` prints parsed arguments and can expose
    values. For secret-bearing bodies, avoid shell arguments and output
    logs; the script's manual describes how to read a JSON body from
    standard input.

# Module reference {#module-reference}

The examples above are a starting point. For the actual method names, arguments, and return conventions, follow the Markdown reference kept beside each module's Perl source. Those sidecars are the maintained method reference; this article stays focus...

[`Cloudflare::API`](lib/Cloudflare/API.pm.md)

: Constructor options, environment defaults, resource accessors, low-level requests, and response handling.

[`Cloudflare::API::Accounts`](lib/Cloudflare/API/Accounts.pm.md)



( run in 0.980 second using v1.01-cache-2.11-cpan-3f962061493 )