> ## Documentation Index
> Fetch the complete documentation index at: https://www.integrate.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ETL: Select with Curl as Rest API Destination

> Configure the REST API destination to write data to any HTTP endpoint. Step-by-step tutorial using HubSpot contacts as a working example.

Writing data to REST APIs essentially works in the same manner as reading data from REST APIs - using simple HTTP requests. HTTP requests are comprised of 4 parts:

* **Method** - the most common are GET (used to read data) and POST (to write data).
* **URL** - specifies the resource to read/write
* **Headers** - specify additional information to the server (e.g. authentication keys, request body format)
* **Body** - usually contains the data to send to the server in JSON or query string format)

In this tutorial, we'll use the [Curl](/etl/curl/ "Link: /etl/curl/") function to make HTTP requests to create Contact in Hubspot.

According to [Hubspot docs](https://developers.hubspot.com/docs/api/crm/contacts "Link: https://developers.hubspot.com/etl/methods/contacts/create_or_update"), for each Contact, we have to create an Authorization header containing your Hubspot token and a JSON string of the Contact properties in the following form to submit in the request body:

```json theme={null}
{  
  "properties":  
  {  
    "property\_name1": "property value",  
    "property\_name2": "property value",  
    "property\_name3": "property value",  
    ...  
  }  
}
```

In our package, we first read data from a Contacts table in a source database.

<Frame>
  <img src="https://mintcdn.com/integrateio/HSGmKiO3soPLENmi/images/creating-packages/using-components-select-rest-api-destination/image-1.png?fit=max&auto=format&n=HSGmKiO3soPLENmi&q=85&s=523c5a32d987254d622ce60a3a647a39" alt="Pipeline reading contacts from a source database table" width="1200" height="1231" data-path="images/creating-packages/using-components-select-rest-api-destination/image-1.png" />
</Frame>

In the second component, we create a field to hold the URL string, and then generate the headers and the properties JSON string.

<Frame>
  <img src="https://mintcdn.com/integrateio/HSGmKiO3soPLENmi/images/creating-packages/using-components-select-rest-api-destination/image-2.png?fit=max&auto=format&n=HSGmKiO3soPLENmi&q=85&s=8f4733ce17d720f6d03a627b475a0b8a" alt="Select component building URL, headers, and JSON properties" width="1200" height="585" data-path="images/creating-packages/using-components-select-rest-api-destination/image-2.png" />
</Frame>

Use the CONCAT function to create the Authorization header (see [here](/etl/concat/) for more information on CONCAT.) The Authorization header contains the literal string '"Authorization": "Bearer ' concatenated with the Hubspot token (which we store in a package variable - `$HUBSPOT_TOKEN`).

```sql theme={null}
CONCAT('{"Authorization": "Bearer ','$HUBSPOT\_TOKEN','","Content-type": "application/json"}')
```

The properties JSON string is generated using Integrate.io ETL's functions to build nested objects [TOMAP](/etl/tomap/ "Link: /etl/tomap/") and [ToJson](/etl/tojson/) that returns a JSON string.

```sql theme={null}
ToJson(TOMAP('properties', TOMAP('first\_name',first\_name,'last\_name',last\_name,'email',email,'company',company,'phone',phone,'address',address,'city',city,'state',state,'zip',zip)))
```

In the third component, the request is made, per record coming in from the source table, and a response is returned.

<Frame>
  <img src="https://mintcdn.com/integrateio/HSGmKiO3soPLENmi/images/creating-packages/using-components-select-rest-api-destination/image-3.png?fit=max&auto=format&n=HSGmKiO3soPLENmi&q=85&s=5546d740dcae7f6ce7edadef064d23d5" alt="Curl function making a POST request with URL, headers, and body" width="1200" height="504" data-path="images/creating-packages/using-components-select-rest-api-destination/image-3.png" />
</Frame>

Using the Curl function (for more information about Curl see [this](/etl/curl/) doc), we pass in the url, headers, and properties fields and define the method as "POST".

```bash theme={null}
Curl(url, 'POST', headers, properties)
```

In the fourth component we parse the API response. The response contains a status code, headers and a body. The status code determines whether the request was successful or not (200 is returned on success. Read more [here](https://legacydocs.hubspot.com/docs/faq/api-error-responses#:~:text=In%20addition%2C%20HubSpot%20has%20several,the%20authentication%20provided%20is%20invalid.\&text=429%20Too%20many%20requests%20%2D%20Returned,working%20within%20those%20limits%20here.)). The body contains the Contact data that was written if the status was successful or an error message if the status wasn't successful.

<Frame>
  <img src="https://mintcdn.com/integrateio/HSGmKiO3soPLENmi/images/creating-packages/using-components-select-rest-api-destination/image-4.png?fit=max&auto=format&n=HSGmKiO3soPLENmi&q=85&s=d05818dd9f8c13e697abefcdebb73cac" alt="Parsing the API response status code and body fields" width="1200" height="555" data-path="images/creating-packages/using-components-select-rest-api-destination/image-4.png" />
</Frame>

```bash theme={null}
api\_response#'body'  
  
api\_response#'status'
```

Finally, the Contact's first name, last name, company, and email along with the response code and body field are stored into a database log table. This helps us monitor the process.

In the same manner, you can write data to any REST API endpoint - simply go through the API docs, build the URL and request body using the source data and check the response to make sure the returned response indicates success.
