cloudflare/cloudflare-typescript

Public

mirrored from https://github.com/cloudflare/cloudflare-typescriptAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0da2321de9ef80aebb7242994de8e8b475a9a404

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

README.md

396lines · modecode

1# Cloudflare TypeScript API Library
2
3[![NPM version](https://img.shields.io/npm/v/cloudflare.svg)](https://npmjs.org/package/cloudflare) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/cloudflare)
4
5This library provides convenient access to the Cloudflare REST API from server-side TypeScript or JavaScript.
6
7The REST API documentation can be found on [developers.cloudflare.com](https://developers.cloudflare.com/api). The full API of this library can be found in [api.md](api.md).
8
9## MCP Server
10
11Use the Cloudflare MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
12
13[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=cloudflare-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImNsb3VkZmxhcmUtbWNwIl0sImVudiI6eyJDTE9VREZMQVJFX0FQSV9UT0tFTiI6IlNuM2xaSlRCWDZra2c3T2RjQlVBeE9POTYzR0VJeUdRcW5GVE9GWVkiLCJDTE9VREZMQVJFX0FQSV9LRVkiOiIxNDRjOWRlZmFjMDQ5NjljN2JmYWQ4ZWZhYThlYTE5NCIsIkNMT1VERkxBUkVfRU1BSUwiOiJ1c2VyQGV4YW1wbGUuY29tIiwiQ0xPVURGTEFSRV9BUElfVVNFUl9TRVJWSUNFX0tFWSI6InYxLjAtMTQ0YzlkZWZhYzA0OTY5YzdiZmFkOGVmLTYzMWE0MWQwMDNhMzJkMjVmZTg3ODA4MWVmMzY1YzQ5NTAzZjdmYWRhNjAwZGE5MzVlMjg1MWExYzczMjYwODRiODVjYmY2NDI5YzRiODU5ZGU4NDc1NzMxZGM5MmE5YzMyOTYzMWU2ZDU5ZTZjNzNkYTdiMTk4NDk3MTcyYjRjZWZlMDcxZDkwZDBmNWQyNzE5IiwiQ0xPVURGTEFSRV9BQ0NPVU5UX0lEIjoiZjAzN2U1NmU4OTI5M2EwNTc3NDBkZTY4MWFjOWFjY3AiLCJDTE9VREZMQVJFX1pPTkVfSUQiOiJmMDM3ZTU2ZTg5MjkzYTA1Nzc0MGRlNjgxYWM5YWNjcCJ9fQ)
14[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22cloudflare-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22cloudflare-mcp%22%5D%2C%22env%22%3A%7B%22CLOUDFLARE_API_TOKEN%22%3A%22Sn3lZJTBX6kkg7OdcBUAxOO963GEIyGQqnFTOFYY%22%2C%22CLOUDFLARE_API_KEY%22%3A%22144c9defac04969c7bfad8efaa8ea194%22%2C%22CLOUDFLARE_EMAIL%22%3A%22user%40example.com%22%2C%22CLOUDFLARE_API_USER_SERVICE_KEY%22%3A%22v1.0-144c9defac04969c7bfad8ef-631a41d003a32d25fe878081ef365c49503f7fada600da935e2851a1c7326084b85cbf6429c4b859de8475731dc92a9c329631e6d59e6c73da7b198497172b4cefe071d90d0f5d2719%22%2C%22CLOUDFLARE_ACCOUNT_ID%22%3A%22f037e56e89293a057740de681ac9accp%22%2C%22CLOUDFLARE_ZONE_ID%22%3A%22f037e56e89293a057740de681ac9accp%22%7D%7D)
15
16> Note: You may need to set environment variables in your MCP client.
17
18## Installation
19
20```sh
21npm install cloudflare
22```
23
24## Usage
25
26The full API of this library can be found in [api.md](api.md).
27
28<!-- prettier-ignore -->
29```js
30import Cloudflare from 'cloudflare';
31
32const client = new Cloudflare({
33 apiToken: process.env['CLOUDFLARE_API_TOKEN'], // This is the default and can be omitted
34});
35
36const zone = await client.zones.create({
37 account: { id: '023e105f4ecef8ad9ca31a8372d0c353' },
38 name: 'example.com',
39 type: 'full',
40});
41
42console.log(zone.id);
43```
44
45### Request & Response types
46
47This library includes TypeScript definitions for all request params and response fields. You may import and use them like so:
48
49<!-- prettier-ignore -->
50```ts
51import Cloudflare from 'cloudflare';
52
53const client = new Cloudflare({
54 apiToken: process.env['CLOUDFLARE_API_TOKEN'], // This is the default and can be omitted
55});
56
57const params: Cloudflare.ZoneCreateParams = {
58 account: { id: '023e105f4ecef8ad9ca31a8372d0c353' },
59 name: 'example.com',
60 type: 'full',
61};
62const zone: Cloudflare.Zone = await client.zones.create(params);
63```
64
65Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
66
67## File uploads
68
69Request parameters that correspond to file uploads can be passed in many different forms:
70
71- `File` (or an object with the same structure)
72- a `fetch` `Response` (or an object with the same structure)
73- an `fs.ReadStream`
74- the return value of our `toFile` helper
75
76```ts
77import fs from 'fs';
78import fetch from 'node-fetch';
79import Cloudflare, { toFile } from 'cloudflare';
80
81const client = new Cloudflare();
82
83// If you have access to Node `fs` we recommend using `fs.createReadStream()`:
84await client.kv.namespaces.values.update('0f2ac74b498b48028cb68387c421e279', 'My-Key', {
85 account_id: '023e105f4ecef8ad9ca31a8372d0c353',
86 value: fs.createReadStream('/path/to/file'),
87});
88
89// Or if you have the web `File` API you can pass a `File` instance:
90await client.kv.namespaces.values.update('0f2ac74b498b48028cb68387c421e279', 'My-Key', {
91 account_id: '023e105f4ecef8ad9ca31a8372d0c353',
92 value: new File(['my bytes'], 'file'),
93});
94
95// You can also pass a `fetch` `Response`:
96await client.kv.namespaces.values.update('0f2ac74b498b48028cb68387c421e279', 'My-Key', {
97 account_id: '023e105f4ecef8ad9ca31a8372d0c353',
98 value: await fetch('https://somesite/file'),
99});
100
101// Finally, if none of the above are convenient, you can use our `toFile` helper:
102await client.kv.namespaces.values.update('0f2ac74b498b48028cb68387c421e279', 'My-Key', {
103 account_id: '023e105f4ecef8ad9ca31a8372d0c353',
104 value: await toFile(Buffer.from('my bytes'), 'file'),
105});
106await client.kv.namespaces.values.update('0f2ac74b498b48028cb68387c421e279', 'My-Key', {
107 account_id: '023e105f4ecef8ad9ca31a8372d0c353',
108 value: await toFile(new Uint8Array([0, 1, 2]), 'file'),
109});
110```
111
112## Handling errors
113
114When the library is unable to connect to the API,
115or if the API returns a non-success status code (i.e., 4xx or 5xx response),
116a subclass of `APIError` will be thrown:
117
118<!-- prettier-ignore -->
119```ts
120const zone = await client.zones
121 .get({ zone_id: '023e105f4ecef8ad9ca31a8372d0c353' })
122 .catch(async (err) => {
123 if (err instanceof Cloudflare.APIError) {
124 console.log(err.status); // 400
125 console.log(err.name); // BadRequestError
126 console.log(err.headers); // {server: 'nginx', ...}
127 } else {
128 throw err;
129 }
130 });
131```
132
133Error codes are as follows:
134
135| Status Code | Error Type |
136| ----------- | -------------------------- |
137| 400 | `BadRequestError` |
138| 401 | `AuthenticationError` |
139| 403 | `PermissionDeniedError` |
140| 404 | `NotFoundError` |
141| 422 | `UnprocessableEntityError` |
142| 429 | `RateLimitError` |
143| >=500 | `InternalServerError` |
144| N/A | `APIConnectionError` |
145
146### Retries
147
148Certain errors will be automatically retried 2 times by default, with a short exponential backoff.
149Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
150429 Rate Limit, and >=500 Internal errors will all be retried by default.
151
152You can use the `maxRetries` option to configure or disable this:
153
154<!-- prettier-ignore -->
155```js
156// Configure the default for all requests:
157const client = new Cloudflare({
158 maxRetries: 0, // default is 2
159});
160
161// Or, configure per-request:
162await client.zones.get({ zone_id: '023e105f4ecef8ad9ca31a8372d0c353' }, {
163 maxRetries: 5,
164});
165```
166
167### Timeouts
168
169Requests time out after 1 minute by default. You can configure this with a `timeout` option:
170
171<!-- prettier-ignore -->
172```ts
173// Configure the default for all requests:
174const client = new Cloudflare({
175 timeout: 20 * 1000, // 20 seconds (default is 1 minute)
176});
177
178// Override per-request:
179await client.zones.edit({ zone_id: '023e105f4ecef8ad9ca31a8372d0c353' }, {
180 timeout: 5 * 1000,
181});
182```
183
184On timeout, an `APIConnectionTimeoutError` is thrown.
185
186Note that requests which time out will be [retried twice by default](#retries).
187
188## Auto-pagination
189
190List methods in the Cloudflare API are paginated.
191You can use the `for await … of` syntax to iterate through items across all pages:
192
193```ts
194async function fetchAllAccounts(params) {
195 const allAccounts = [];
196 // Automatically fetches more pages as needed.
197 for await (const account of client.accounts.list()) {
198 allAccounts.push(account);
199 }
200 return allAccounts;
201}
202```
203
204Alternatively, you can request a single page at a time:
205
206```ts
207let page = await client.accounts.list();
208for (const account of page.result) {
209 console.log(account);
210}
211
212// Convenience methods are provided for manually paginating:
213while (page.hasNextPage()) {
214 page = await page.getNextPage();
215 // ...
216}
217```
218
219## Advanced Usage
220
221### Accessing raw Response data (e.g., headers)
222
223The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
224
225You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.
226
227<!-- prettier-ignore -->
228```ts
229const client = new Cloudflare();
230
231const response = await client.zones
232 .create({
233 account: { id: '023e105f4ecef8ad9ca31a8372d0c353' },
234 name: 'example.com',
235 type: 'full',
236 })
237 .asResponse();
238console.log(response.headers.get('X-My-Header'));
239console.log(response.statusText); // access the underlying Response object
240
241const { data: zone, response: raw } = await client.zones
242 .create({
243 account: { id: '023e105f4ecef8ad9ca31a8372d0c353' },
244 name: 'example.com',
245 type: 'full',
246 })
247 .withResponse();
248console.log(raw.headers.get('X-My-Header'));
249console.log(zone.id);
250```
251
252### Making custom/undocumented requests
253
254This library is typed for convenient access to the documented API. If you need to access undocumented
255endpoints, params, or response properties, the library can still be used.
256
257#### Undocumented endpoints
258
259To make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.
260Options on the client, such as retries, will be respected when making these requests.
261
262```ts
263await client.post('/some/path', {
264 body: { some_prop: 'foo' },
265 query: { some_query_arg: 'bar' },
266});
267```
268
269#### Undocumented request params
270
271To make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented
272parameter. This library doesn't validate at runtime that the request matches the type, so any extra values you
273send will be sent as-is.
274
275```ts
276client.foo.create({
277 foo: 'my_param',
278 bar: 12,
279 // @ts-expect-error baz is not yet public
280 baz: 'undocumented option',
281});
282```
283
284For requests with the `GET` verb, any extra params will be in the query, all other requests will send the
285extra param in the body.
286
287If you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request
288options.
289
290#### Undocumented response properties
291
292To access undocumented response properties, you may access the response object with `// @ts-expect-error` on
293the response object, or cast the response object to the requisite type. Like the request params, we do not
294validate or strip extra properties from the response from the API.
295
296### Customizing the fetch client
297
298By default, this library uses `node-fetch` in Node, and expects a global `fetch` function in other environments.
299
300If you would prefer to use a global, web-standards-compliant `fetch` function even in a Node environment,
301(for example, if you are running Node with `--experimental-fetch` or using NextJS which polyfills with `undici`),
302add the following import before your first import `from "Cloudflare"`:
303
304```ts
305// Tell TypeScript and the package to use the global web fetch instead of node-fetch.
306// Note, despite the name, this does not add any polyfills, but expects them to be provided if needed.
307import 'cloudflare/shims/web';
308import Cloudflare from 'cloudflare';
309```
310
311To do the inverse, add `import "cloudflare/shims/node"` (which does import polyfills).
312This can also be useful if you are getting the wrong TypeScript types for `Response` ([more details](https://github.com/cloudflare/cloudflare-typescript/tree/main/src/_shims#readme)).
313
314### Logging and middleware
315
316You may also provide a custom `fetch` function when instantiating the client,
317which can be used to inspect or alter the `Request` or `Response` before/after each request:
318
319```ts
320import { fetch } from 'undici'; // as one example
321import Cloudflare from 'cloudflare';
322
323const client = new Cloudflare({
324 fetch: async (url: RequestInfo, init?: RequestInit): Promise<Response> => {
325 console.log('About to make a request', url, init);
326 const response = await fetch(url, init);
327 console.log('Got response', response);
328 return response;
329 },
330});
331```
332
333Note that if given a `DEBUG=true` environment variable, this library will log all requests and responses automatically.
334This is intended for debugging purposes only and may change in the future without notice.
335
336### Configuring an HTTP(S) Agent (e.g., for proxies)
337
338By default, this library uses a stable agent for all http/https requests to reuse TCP connections, eliminating many TCP & TLS handshakes and shaving around 100ms off most requests.
339
340If you would like to disable or customize this behavior, for example to use the API behind a proxy, you can pass an `httpAgent` which is used for all requests (be they http or https), for example:
341
342<!-- prettier-ignore -->
343```ts
344import http from 'http';
345import { HttpsProxyAgent } from 'https-proxy-agent';
346
347// Configure the default for all requests:
348const client = new Cloudflare({
349 httpAgent: new HttpsProxyAgent(process.env.PROXY_URL),
350});
351
352// Override per-request:
353await client.zones.delete(
354 { zone_id: '023e105f4ecef8ad9ca31a8372d0c353' },
355 {
356 httpAgent: new http.Agent({ keepAlive: false }),
357 },
358);
359```
360
361## Semantic versioning
362
363This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
364
3651. Changes that only affect static types, without breaking runtime behavior.
3661. Changes to library internals which are technically public but not intended or documented for external use.
3671. Changes that we do not expect to impact the vast majority of users in practice.
368
369## Requirements
370
371TypeScript >= 4.5 is supported.
372
373The following runtimes are supported:
374
375- Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more)
376- Node.js 18 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.
377- Deno v1.28.0 or higher.
378- Bun 1.0 or later.
379- Cloudflare Workers.
380- Vercel Edge Runtime.
381- Jest 28 or greater with the `"node"` environment (`"jsdom"` is not supported at this time).
382- Nitro v2.6 or greater.
383
384Note that React Native is not supported at this time.
385
386If you are interested in other runtime environments, please open or upvote an issue on GitHub.
387
388## Maintenance
389
390This SDK is actively maintained, however, many issues are tracked outside of GitHub on internal Cloudflare systems. Members of the community are welcome to join and discuss your issues during our twice monthly triage meetings. For urgent issues, please contact [Cloudflare support](https://www.support.cloudflare.com/s/?language=en_US).
391
392* [Community triage meeting](https://calendar.google.com/calendar/embed?src=c_dbf6ce250643f2e60f806d28f3fc09a9de24cbe0ab3ffb699838303d2adfc9e4%40group.calendar.google.com&ctz=America%2FLos_Angeles)
393
394## Contributing
395
396See [the contributing documentation](./CONTRIBUTING.md).
397