The HTTP Request node is the node you reach for when n8n has no dedicated integration for the service you need, which is most of the time once you leave the popular SaaS apps. It can call any REST API, and a surprising amount of "I need a custom node" turns out to be a correctly configured HTTP Request node instead.
TL;DR: Use a Predefined Credential Type whenever n8n has a node for the service even if you're calling it through HTTP Request, because it manages token refresh for you. Drop to Generic Credential Type (Header auth or Bearer auth for most modern APIs) only when there's no predefined option. Send structured data with Send Query Parameters and Send Body (pick the right Body Content Type), not hand-built URLs. For multi-page results, enable the built-in Pagination option instead of building a loop. And when you're staring at a curl example in someone's API docs, paste it into Import cURL rather than transcribing it by hand.
Start by importing the cURL command
Most API documentation gives you a curl example. Do not retype it field by field. In the HTTP Request node's Parameters tab, select Import cURL, paste the command, and select Import. n8n parses the method, URL, headers, query string, and body into the node fields. This overwrites any existing configuration in the node, so import into a fresh node.
One catch worth knowing before it bites you: Import cURL brings every parameter value in as a string. If your API cares about numbers or booleans being real JSON types ("limit": 50 vs "limit": "50"), switch the relevant section from Using Fields Below to Using JSON and paste a proper JSON object so the types survive.
Importing also teaches you the node faster than any tutorial, because you can see how a known-good request maps onto the fields.
Method and URL
The Method dropdown covers DELETE, GET, HEAD, OPTIONS, PATCH, POST, and PUT. URL is the endpoint. That part is uninteresting; the decisions live in authentication, body, and pagination.
A small but real tip: keep query filters out of the URL. It's tempting to write https://api.example.com/users?status=active&limit=50 directly into the URL field, but you lose n8n's array formatting and expression support. Put the base URL in URL and the filters in Send Query Parameters.
Authentication: predefined first, generic only when forced
The single most useful default: if n8n has a node for the service (Asana, Airtable, and many others), use Predefined Credential Type in the HTTP Request node and pick that credential. You get token storage and, for OAuth services, automatic refresh, without configuring endpoints yourself. n8n explicitly recommends this whenever a predefined type exists. This is the same mechanism behind custom API operations on supported platforms.
When there's no predefined type, switch to Generic Credential Type. The supported generic methods are:
-
Basic auth - username and password.
-
Bearer auth - a single token sent as
Authorization: Bearer <token>. This is the right choice for most modern token-based APIs. -
Header auth - a custom header name and value (for APIs that want
X-API-Key: ...rather than a Bearer token). -
Query auth - a single key/value pair appended to the query string.
-
Digest auth and OAuth1 API - older schemes, configure only if the service requires them.
-
OAuth2 API - supports Authorization Code, Client Credentials, and PKCE grant types.
-
Custom auth - the escape hatch.
Reach for Custom auth when one of the simple types isn't enough, for example two auth headers, or a header plus a query key. It takes a JSON object with headers, qs, and body keys:
{
"headers": {
"X-AUTH-USERNAME": "username",
"X-AUTH-PASSWORD": "password"
},
"qs": {
"apikey": "my-api-key"
}
}
For OAuth2 Client Credentials (machine-to-machine, no user login), select Client Credentials as the Grant Type, enter the Access Token URL (usually ending in /token), Client ID, Client Secret, and choose whether to send credentials in the Header or the Body. n8n handles fetching and reusing the token. That alone is a reason to use a credential rather than hand-building an Authorization header in Send Headers: the credential survives token expiry, a hardcoded header does not.
Never paste a live API key straight into a header value in the node. Create it as a credential so it's stored encrypted and doesn't leak into exported workflow JSON.
Sending query parameters and headers
Turn on Send Query Parameters for filters, and Send Headers for metadata like content negotiation. Both offer Using Fields Below (Name/Value pairs, add more with Add Parameter) or Using JSON. Use Fields Below when values are static or come from single expressions; use JSON when you're passing a whole object through from an upstream node.
Arrays in query strings are a common source of silent breakage because APIs disagree on the format. When Send Query Parameters is on, the Array Format in Query Parameters option controls it:
-
No Brackets:
foo=bar&foo=qux -
Brackets Only:
foo[]=bar&foo[]=qux -
Brackets with Indices:
foo[0]=bar&foo[1]=qux
If an array filter "isn't working," this is the first thing to check against the API docs.
Sending a body: pick the content type deliberately
Turn on Send Body, then choose the Body Content Type that matches what the API expects. Getting this wrong produces 400s that look like auth problems but aren't.
-
JSON - the default for modern REST APIs. Use Using Fields Below for flat key/value pairs, or Using JSON when you need nested objects or want to pass a full object from a previous node.
-
Form URLencoded (
application/x-www-form-urlencoded) - older form-style endpoints. Either Name/Value fields or a single Body string likefieldname1=value1&fieldname2=value2. -
Form-Data (
multipart/form-data) - for file uploads. Set Parameter Type to Form Data for text fields, or n8n Binary File to attach a file, where Input Data Field Name is the name of the incoming binary field (oftendata). -
n8n Binary File - send a whole file's contents as the raw body; point Input Data Field Name at the binary field.
-
Raw - you set the Content Type header and paste the Body verbatim. Use this for XML, NDJSON, or anything the structured types don't cover.
For file uploads specifically, the most common mistake is leaving the type on JSON. A binary upload needs Form-Data with n8n Binary File, or the n8n Binary File content type directly.
If you're doing heavier data shaping before the request (building a payload, batching items, reshaping nested arrays), the Code node upstream is usually cleaner than fighting the field UI.
Pagination: use the built-in feature, not a manual loop
The most common reason people build a loop with the HTTP Request node is to fetch every page of a paginated API. You usually don't have to. The node has a built-in Pagination option. Select Add Option and choose Pagination.
Before configuring it, run the request once without pagination and look at the response, because the right setup depends entirely on how the API reports the next page. There are two Pagination Mode values that matter (plus Off).
Mode 1: Update a Parameter in Each Request
Use this when you target pages by number. Set Pagination Mode to Update a Parameter in Each Request, set Type to Query, enter the parameter Name (often page), toggle Expression on for Value, and enter:
{{ $pageCount + 1 }}
$pageCount is the number of pages fetched so far and starts at zero. Most APIs number pages from one, so $pageCount + 1 requests page one on the first loop, page two on the second, and so on. If the API paginates through the body instead (common for POST search endpoints), set the Method to POST and choose Body as the Type, with the same {{ $pageCount + 1 }} value.
Mode 2: Response Contains Next URL
Use this when the API hands you the next page's URL in its response, which is the cleaner pattern. Set Pagination Mode to Response Contains Next URL and put an expression in Next URL that reads the URL out of the last response. For an API that returns it as next-page in the body:
{{ $response.body["next-page"] }}
Adjust the path to your API's shape. If the next link comes back in a header (a Link header, say), read from $response.headers instead. Pagination stops when that expression resolves to empty.
One more thing to set on real APIs: page size. Turn on Send Query Parameters in the main node parameters and add a limit (or whatever the API calls it) so each page is as large as the API allows. Fewer, bigger pages means fewer requests and less chance of tripping a rate limit.
Rate limits and large responses
These two gotchas account for most "it worked in testing, failed in production" HTTP Request failures.
For rate limits, use the Batching option (under Add Option). Set Items per Batch to control how many input items fire per batch, and Batch Interval to wait a number of milliseconds between batches. If you have 500 input items and the API allows 60 requests a minute, batching with an interval keeps you under the cap instead of getting a wall of 429s. This is the node's built-in throttle and it's better than a manual Wait-node loop.
For large responses, two settings matter. Timeout sets how long the node waits for the server to start responding, in milliseconds, raise it for slow report-generation endpoints. And under the Response option, set Response Format to File (with Put Output in Field naming the output field) when you're downloading a big payload or an actual file, so n8n streams it to a binary field instead of trying to hold a giant JSON blob in memory.
Two more Response toggles worth knowing: Include Response Headers and Status returns the full response, not just the body, which you need when reading pagination links or rate-limit headers. And Never Error makes the node return success on any status code, so you can inspect a 4xx body and branch on it yourself instead of having the workflow halt. Use Never Error sparingly; failing loudly is usually what you want, and silently swallowing a 500 hides real problems.
Quick reference: which option for which problem
-
API needs a token n8n already manages -> Predefined Credential Type.
-
Modern API, single token -> Generic Credential Type > Bearer auth.
-
API wants a custom key header -> Header auth. Two headers or header-plus-query -> Custom auth with a JSON object.
-
Uploading a file -> Send Body > Form-Data > n8n Binary File.
-
Multi-page results, page numbers -> Pagination > Update a Parameter in Each Request with
{{ $pageCount + 1 }}. -
Multi-page results, next-link in response -> Pagination > Response Contains Next URL with
{{ $response.body["next-page"] }}. -
Getting 429s -> Batching with an interval.
-
Downloading a large file -> Response Format > File.
If the request is a trigger rather than an outbound call (you want an external service to call your n8n workflow), that's the Webhook node, not this one.
FAQ
What's the difference between Predefined and Generic Credential Type in the HTTP Request node?
Predefined Credential Type reuses a credential for a service n8n already supports (like Asana or Airtable) and manages token storage and OAuth refresh for you. Generic Credential Type is for services with no n8n node, where you configure the auth method (Basic, Bearer, Header, Query, OAuth, Digest, or Custom) yourself.
How do I paginate an API with the n8n HTTP Request node?
Select Add Option > Pagination. If the API uses page numbers, choose Update a Parameter in Each Request, set the parameter Type to Query, and use the expression {{ $pageCount + 1 }} as the value. If the response includes a next-page URL, choose Response Contains Next URL and set Next URL to an expression like {{ $response.body["next-page"] }}.
Can I import a curl command into n8n?
Yes. In the node's Parameters tab, select Import cURL, paste the command, and select Import. n8n maps the method, URL, headers, query parameters, and body into the node. Note that all values import as strings, so switch a section to Using JSON if you need to preserve number or boolean types.
How do I send a file with the HTTP Request node?
Turn on Send Body, set Body Content Type to Form-Data, add a parameter with Parameter Type set to n8n Binary File, and point Input Data Field Name at the incoming binary field (commonly data). For a raw single-file body, use the n8n Binary File content type directly.
How do I avoid hitting API rate limits?
Use the Batching option to set Items per Batch and a Batch Interval in milliseconds, which throttles how fast requests go out. Also fetch larger pages (set a higher limit query parameter) so you make fewer total calls, and raise the Timeout for slow endpoints.
How do I get headers and the status code back, not just the body?
Under the Response option, turn on Include Response Headers and Status. The node then returns the full response including headers and the status code, which you need for reading pagination links from headers or inspecting rate-limit metadata.
If you're wiring up an API that n8n doesn't have a node for and the auth or pagination is fighting you, that's exactly the kind of thing we build and debug for clients at n8n Logic. Get the request working once, save it as a sub-workflow, and reuse it everywhere.