Back to all articles


Updated on February 8, 2024

I was recently working on a project where I needed to integrate an external API using HTTP cURL requests. It was my first time doing this and I had a lot of problems figuring this out. I wrote this post so I can remember my cURL API calls for next time, and maybe it can help you as well. 

The API calls and functions I’m using in this post are all working examples on PHP -v 5.6.

REST API calls with cURL, PHP and json

PHP cURL Basics

cURL stands for ‘Client URL Library’ and it allows you to connect and communicate with different types of servers with many different types of protocols (HTTP, https, FTP, proxy, cookies, …). More info about how cURL actually works can be found in the official PHP documentation. This article will provide more in-depth examples for integrating your applications.

I’ve received a lot of responses on ‘how does cURL actually work’ and I get the feeling that people don’t know what’s going on in a cURL call. Before we start with the article and our cURL setup, I’ve added a simple example of a plain cURL request. The request will return the API response as a string.

// create & initialize a curl session
$curl = curl_init();

// set our url with curl_setopt()
curl_setopt($curl, CURLOPT_URL, "");

// return the transfer as a string, also with setopt()
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

// curl_exec() executes the started curl session
// $output contains the output string
$output = curl_exec($curl);

// close curl resource to free up system resources
// (deletes the variable made by curl_init)

Note that we stored our curl_exec() in a variable $output. This $output variable is still available in our program even after we closed it with curl_close(). So after we did our call and closed the connection, we can still access the result using our $output variable.

Now that we understand the basics, let’s try to put this into a function we can reuse within our application.

PHP cURL setup

Implementing an external API into your project is probably going to take more than just one API call and from different pages in your project. This is why I’ve created a ‘simple’ PHP script that allows us to call this function, with a set of parameters, and a cURL request will be done.

Make sure to put this code into a file or place that can be accessed by your entire app or website. (I’ve updated this function so we’ll be able to define the headers when we’re making the call. I’ve added a section for custom headers at the bottom!)

function callAPI($method, $url, $data){
   $curl = curl_init();
   switch ($method){
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);			 					
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      'APIKEY: 111111111111111111111',
      'Content-Type: application/json',
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   // EXECUTE:
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   return $result;

This is a basic setup for doing a cURL call and I’m using a switch statement to check if the API call will be a POST, PUT, or something else (get or delete). I’ll go deeper into the switch case while we’re doing the specific requests.

I’m using if-statements inside the switch-case to see if we want to provide JSON data into our call or not. For the POST and PUT request the if-statement is not really necessary because we’re only using POST or PUT with data, but it’s an extra security to make sure our call function won’t break.

PHP cURL GET request

The most simple API call is the GET call, so let’s start with that! Our callAPI function expects 3 parameters: $method, $url and $data. We need to give those parameters to all our API calls, so for a cURL GET, we can just set $data on false because we are not passing any data with a GET call.

$get_data = callAPI('GET', ''.$user['User']['customer_id'], false);
$response = json_decode($get_data, true);
$errors = $response['response']['errors'];
$data = $response['response']['data'][0];

$get_data already returns all the data we want from the API in a json string. I’m using $response to convert the json string back to a usable PHP array. You can skip those steps if you want, this is my personal preference. I’m also using the extra $errors and $data arrays to store the actual data and errors.

PHP cURL POST request

Obviously, a POST request does require data. Make sure your json-data is correct, otherwise the request will keep returning errors. Although… If we receive errors from the API, that means our calls are working 😉

In my example I’m using the CakePHP syntax for setting up my json array, so don’t mind that.

$data_array =  array(
      "customer"        => $user['User']['customer_id'],
      "payment"         => array(
            "number"         => $this->request->data['account'],
            "routing"        => $this->request->data['routing'],
            "method"         => $this->request->data['method']
$make_call = callAPI('POST', '', json_encode($data_array));
$response = json_decode($make_call, true);
$errors   = $response['response']['errors'];
$data     = $response['response']['data'][0];

Because we’re doing an API call with json data, I’m converting my PHP array to a json string with json_encode($data_array);. The response will come in as a json string again, so I’m using json_decode($make_call, true); to convert the json string back to a usable PHP array. Same as we did in our GET call, so you can skip these steps again if you don’t need them.

PHP cURL PUT request

The PUT request is almost the same as the POST request. I had a hard time figuring out how to pass data into a PUT call. If we take a look at our callAPI() function, you see that I changed some things up between the PUT and the POST request. We can still use the same parameters in our callAPI() function as always.

$data_array =  array(
   "amount" => (string)($lease['amount'] / $tenant_count)
$update_plan = callAPI('PUT', ''.$lease['plan_id'], json_encode($data_array));
$response = json_decode($update_plan, true);
$errors = $response['response']['errors'];
$data = $response['response']['data'][0];


The delete request is very simple again. We can just hit the API url with the $id we want to remove and poof… it’s gone forever.

callAPI('DELETE', '' . $id, false);

What with flexible headers?

In the beginning we defined our callAPI function with preset headers. But what if we, for some reason, need to change the headers a bit for another call? We don’t want to write a whole new callAPI function just to edit some headers. Therefore, here’s an option on how to make the preset headers flexible:

function callAPI($method, $url, $data, $headers = false){
   $curl = curl_init();
   switch ($method){
   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
       curl_setopt($curl, CURLOPT_HTTPHEADER, array(
          'APIKEY: 111111111111111111111',
          'Content-Type: application/json',
       curl_setopt($curl, CURLOPT_HTTPHEADER, array(
          'APIKEY: 111111111111111111111',
          'Content-Type: application/json',
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   // EXECUTE:

There are 2 differences here from our first function. 1: We’ve added an extra parameter in our function to define if we want to use a custom header or not. I put it to $headers = false to give it a default value. Now we’re not required to enter our headers with every call.

The second change is the if-statement when we’re setting the API headers. If we didn’t give in any headers when we make the call, it’s going to use our default headers instead of crashing. Now we’re ready to add custom headers with our call!

In this example, I’m using search parameters to search for specific data before I’ll pull in all the data with the API. To make the search, I obviously need to be able to add my search query into my callAPI headers. Here’s my example:

Creating custom headers before our call

$one_month_ago = date("Y-m-d", strtotime(date("Y-m-d", strtotime(date("Y-m-d"))) . "-1 month"));
$rent_header = 'Search: and[][created][greater]=' . $one_month_ago . '%and[][created][less]=' . date('Y-m-d') . '%';
//the actual call with custom search header
$make_call = callAPI('GET', '', false, $rent_header);

This is just an example on how to add headers. My example is to get all rows where a rent was paid in the last 30 days. $one_month_ago is just a helper variable. The $rent_header is the actual header I want to add to my default headers. This needs to be a string!!

When you’ve set the header, you can just do a regular api call and add your new header at the end.

I didn’t need to use any other API call methods like patch or purge or anything like that. These you need to figure out yourself. If there’s some magic going on in this post I hope my examples can give you a better understanding.

I recently wrote a part 2 for this post, that will talk about generating an AUTH-key (utoken) before we make our calls. Make sure to check it out here as well!

Leave a Reply

Your email address will not be published. Required fields are marked *


  • Zeth Larsson says:

    Thanks for a good article about cURL.
    But I’v still a problem.
    In your first simple example, I get empty result, what ever I do.
    I tryed: curl_setopt($curl, CURLOPT_URL, “”);
    Where alone give perfect answer in the browser.
    I then tryed:
    $ip = “”
    curl_setopt($curl, CURLOPT_URL, $ip)
    With the same result, empty output!
    Now after many hours, I would really appreciate help on that! Regards /Zeth

    • weichie says:

      Hi Zeth, thank you for your message. What exactly do you mean with my first example? If you only did the Basic and did not continue with the PHP cURL Setup step, then indeed the code will return nothing as we’re not returning or echo’ing anything there.

      You can try “echo $output;” after the curl_close($curl); to echo something. Please ensure that your PHP environment has the cURL extension enabled. You can do this by checking your php.ini file or running phpinfo() to see if cURL is listed as enabled.

  • Farkas says:

    Hello! I would have a problem wanting to delete, I type DELETE and for some reason it’s like getting a GET. Can you help me with what’s not good? Everything is like here and I don’t understand. Thanks in advance for your help! Wolf
    Sorry, I wrote in Hungarian: D

    • Bob Weichler says:

      Hi Farkas, Thank you for posting your feedback. Do you have a code example for me, please?

  • Şahin says:

    POSTing from a.php to b.php. I save it to the database and positive/negative results are returned. How can I print this result to my a.php file?

  • Talha Rafique says:

    thanks, man,
    you saved my 2 days.

  • Pedro henrique says:

    One doubt supose I send on curl from my login page to my api it handles login data.

    In my api how to receive the data with come in curl? If is not possible have other options.


  • Paolo says:

    Great article! but I can access my API. Can you help me.
    The Curl that I’ve tested is:
    curl –request GET –header “Accept: application/json” –header ‘X-CLIENT-AUTH: 111111111111’ ‘’
    How can I put this in PHP?
    Many many tnx!

  • Rick says:

    Hello and thank you for your information.

    I am trying to learn all I can about PHP and web programming. Right now, I am wondering this; when you use cURL to call an API it is used as described on this page. You have a method, you have data and you have an URL. But, is cURL “bi-directional”?

    I mean, you call an API with cURL, but what does the API use to reply with the requested data? cURL too? Because for posting a cURL request you definitely need an URL where the API is installed, but not to reply to that request because the call can come from various sources or webpages. I have successfully used cURL to request data from different APIs but of course, those APIs were already existing. What if I would like to do a page that responds to requests from another page? Do I use cURL in some other way?

    Thank you in advance for any help.

    • Bob Weichler says:

      Hi Rick,
      When you call an API (with cURL, Axios, Ajax, Fetch, …) you need to hit an API endpoint that will simply return the data you requested. Visiting that API endpoint URL in your browser or through Postman will give you the same results (if the API route is public, otherwise you need authentication first)

      A simple example hitting the following URL: will show me my API response. But that endpoint is always there. When you call that URL in cURL, you get the data as response. But the API endpoint is not connected with your app or website. Depending on your programming language, you need to use cURL or Axios or Fetch or …

      Same for authentication, you call a login route with cURL and the API response will give you an auth_token as a return. You need to use that auth_token in any further API calls you make in order to access the protected routes of the API you want to use.

      If you want to create your own API, you need to make sure you create public/private endpoints in your app that look like: – You can name it anything you want, just make sure it returns something useful to the user who is calling your endpoint.

  • Chitra says:

    Dear sir,
    Really i feel happy to read your words. Because mow im in the same boat where you have already travelled. So your pages makes a way to cross the huddles. Im now in my first project. Hope you can help me in this aspect. I have loads of doubts.

  • bali kratom says:

    Thanks for sharing this it’s really helpful for me.

  • samuel says:

    really useful

  • Scott says:

    Greetings from a random stranger on the internet. Just wanted to say thank you for posting this. I normally wear a PERL hat whenever I have the odd need to script something but a recent project made PHP a better choice even though I was not familiar with it at all. This post helped me figure out why my own code was failing so spectacularly. Oh, and I stole the default case statement for my own use. Clever multi use of the $data variable there.

  • abdelhak says:

    Great post very helpful article, i really like it and i like the way you explain the api calls!

  • basicmath says:

    you sir are a gent!

    Thanks for making this available!

  • Rossella Terracciano says:

    I dodn’t understand… i have to put the function code and thecURL post request in the same PHP script (changing the url) if i want to make a request for an authentication, right? which is the order? =( The result should be the authkey but it doeasn’t print it in localhost

  • Tee says:

    i have been using your api function for a while but now it suddenly stopped working. I get connection failure now . Any help would be appreciated.

  • Vikas Sharma says:

    Nice and simple

  • Benjamin says:

    This has been one of the best articles I have seen about cURL API calls, thank you very much

  • Leslie says:

    Thank you recommending me this post, because I’m so in your position when you wrote this post right now and the deadlines are on my throat like theirs no tomorrow

  • PRANAV says:

    Thank you very much!! This helped me a lot.

  • weight loss diets says:

    Pretty! This was a really wonderful article. Thanks for providing these details.

  • goenergia says:

    Thx, works fine!

  • krishna says:
    how i am access this url in php curl
    help me if you able to solve

  • Haider says:

    hi I wanted to apply this on my chatbot can you help in this

  • spamzeiro says:

    This website help me to call API.
    very thx!

  • mahesh says:


  • Dammy Oluwatobi says:

    Hi, this might be a very strange question but i need to verify if a user exist in my database from a curl request, and then return a confirmation code to the request. i am new with php

  • amar singh says:

    Thank you very much. I appreciate. This helped me a lot in my college project.

  • Daniel says:

    Well, might seem a strange question, since nobody asked, but why nobody ever mention the API key? Each user should have a unique api key.
    Why is this ignored?

  • Butterfly Valves says:

    This site definitely has all of the information and
    facts I wanted concerning this subject and didn’t know who to ask.

  • kishor says:

    good site

  • Supreet says:

    Great article.thank you

  • bungee says:

    Great read. Is it possible to GET with a JOIN in cURL? So you can query based on a shared value between tables? I cant seem to figure out how to do this. A possible new topic: using PHP composer – basic set up and test with API. Lots of people struggle there. Thanks again

  • cpvc pipes says:

    magnificent put up, very informative. I wonder why the other
    experts of this sector don’t notice this. You must proceed your writing.

    I am confident, you’ve a huge readers’ base already!

  • Deepak says:

    hello sir
    so can we use this to integrate any api with our website

  • devi says:

    this was very useful to understand various curl methods. I need one help from you.
    I am trying to accomplish same thing using C++. How to send json data as a response to a curl query?

  • Lavinia says:

    Excelente post, with a little change it helped me a lot on my web application. Thanks!

  • Vong Visalsambath says:

    I run node on localhost with 3000 port and I got this error message: failed to connect to localhost port 3000: connection refused.

  • Penni says:

    I read this paragraph completely regarding the difference of most
    up-to-date and preceding technologies, it’s amazing article.

  • Orang dalem says:

    You’re amazing man,, Thanks 🙂

  • tomosa says:

    Thanks man, your work is easy to learn and understand.
    Just a quick question how can I enable my login form to return the api key upon the user log-in ?

  • Harga Karpet masjid says:

    Oh my goodness! Impressive article dude! Thanks, However I
    am encountering troubles with your RSS. I don’t understand why I am
    unable to subscribe to it. Is there anybody getting identical RSS problems?
    Anybody who knows the answer can you kindly respond?

  • sports celebrity says:

    Have you ever thought about publishing an ebook or guest authoring on other sites?
    I have a blog based upon on the same information you discuss and would really like to have you share some stories/information. I know my readers would appreciate
    your work. If you are even remotely interested, feel free to shoot me an e-mail.

  • Bryan Jay Osal says:

    Hi bro can you do fetch api that fetches json file using php from a api url withCRUD? i mean just a simple OOP php so i could understand it . thank you so much man.

  • Wordinbox says:

    I want do task as below :
    My App is hosted on with Login box and Banner Image.

    Now for customer abc,com set cname record to When my page access from, I want him to show his login page or his company logo on my login page.

    Same i want to do for customer domain

    How this can be possible using ur code ?

  • Joan says:

    Hi! Thanks you very much, i don’t try all the options, but the first, works for me.

  • NAGENDRA R says:

    Is there a way that one could use a front-end link that, when a logged-in user clicked, changed the category from 2 to 3 (or “active” to “closed”)? It seems like it should be something that could be done using the rest api.

  • Pritesh sushil singh says:

    good job, its very helpfull

  • Joshua Read says:

    Is there a way that one could use a front-end link that, when a logged-in user clicked, changed the category from 2 to 3 (or “active” to “closed”)? It seems like it should be something that could be done using the rest api.

    • weichie says:

      Hey Joshua, Yes this can be done using the cURL PUT request from this blog-post. In my example I am changing the lease amount to something else. So in your case this would be “category” => 3 instead of “amount” (in my case). Try to use “category” => (string) 3 if your json returns an error. Hope this helps!

  • Israel says:

    Thank you very much. I appreciate. This helped me a lot in my school project.

  • Adam says:

    Thanks, man. this is awesome. although modified it to
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);

    due to the authentication method am using. Thanks

  • Art3mis9 says:

    I’m coding a web app that needs to use oAuth to fetch data. I can’t send the data from the client, for security reasons, so I need to have the client send the request to our own server first which then will make the API call using the credentials and then take the returned data and send it back to the web client.

    Can I do this using PHP cURL? This is my first development project and I’m new to API’s. I stumbled across your post, and the information is great. I’m just struggling with the implementation.

    • weichie says:

      Hey there! Thanks for commenting. A lot of people ask me how this can be done if you need login credentials first. (Generating an auth-key before making the general API call). I’ll try to make a new Blog post about this problem this week!

  • Kalumba Raymond Joseph says:

    wooow this has really been Interesting to know, it has really helped to to understand how cURL works have been using frame works though at times i has getting changes. thumbs up brother peace…….

  • vincenzo says:

    Hi, many thnaks for your tutorial, I’m connecting to a API using cURL and php, the API returns a id token for a specific user. I don’t understand why if I access directly the request url, for example if I put the login url in the browser then i’m able to open other urls without needing the token again. Is the token saved in the header? Many thanks

  • AK says:

    Thanks bro. This helped.

  • Andrew Dzimano says:

    Great help, however, inside the function I needed these two options below for it to work:
    //additional options
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

  • Todd Ferguson says:

    THANK YOU SO MUCH, for posting this. Super helpful and best of all… it actually works!!! Great post!

  • vijay says:

    Thanks, Its works like charms.

  • Rue says:

    Hi i am trying to post username and password for log-in to the API but i am getting an error mesage “Notice: Trying to get property of non-object” when i try to log in..may you please help me with a log-in POST request

  • PHP Developer says:

    Worked for me like a charm. Thanks for such a nice and useful tutorial.

  • rossi says:

    how dos its work if i need du submit an auth-token for authorization ???

    • weichie says:

      I think you can add the following into the options part of the callAPI function:

      curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
      curl_setopt($curl, CURLOPT_USERPWD, “username:password”);

      Or try flexible headers “Authorization: Token xxxxxxxxxxxxxx” (untested)

  • says:

    I really like it wһen peоple get together annd sharе
    opinions. Great sitе, stick ith it!