# Getting Started (EN)

## Getting started

This is a REST-style API that uses JSON for serialization. To start using the API you will need:

  1.Log into WoowUp and get your Api Key from the Configuration/MyAccount section. \
  2.Read the API docs to understand what you can do.

Basics

* All request receive and return data in JSON format.
* Remember to include in the header Basic Authentication when calling any endpoint. [Here](#authentication) you’ll find how to do it.
* To identify a customer use the field “service\_uid”. Normally you will use the email or the ID (DNI, CPF, RUT, Passport) to identify the customer.
* Every time you are going to use service\_uid as part of the URL, first you’ll need to encode it with base64 and then with url encode. You can read here a detailed explanation [here](#how-to-encode-service_uid).
* Valid date formats are: YYYY-mm-dd HH:mm:ss (default in UTC) or ISO8601 format including the timezone Ex: 2004-02-12T15:19:21+03:00
* Normally you’ll include al the Product Information (sku, title, category, stock, etc) within the Create purchase order endpoint. But if you prefer, there is a specific endpoint to synchronize [products](https://woowup-docs.gitbook.io/woowup-developer-docs/api/products#products).
* Before send a purchase order, you need to create the customer if it doesn't exist. In the example you can see how this process works in the "import\_from\_csv.php" file.
* Please, pay attention to the messages of the responses of our API because we will tell you if something is wrong with your requests or the information you send.

### Rate Limiting

The API limits the number of requests per account to ensure service stability. **The default limit is 140 requests per minute.**

The system divides time into 30-second segments and always evaluates two segments: the current one and the previous one. Requests from the current segment count at 100%, while requests from the previous segment are weighted based on elapsed time — the more time has passed, the less they count.

This creates a smooth transition between windows, avoiding the classic fixed-counter problem where a client can double the limit at the reset boundary.

{% code lineNumbers="true" %}

```java
weight     = 1 - (elapsed_seconds / segment_duration)                                                                                                                 
estimated  = (previous_requests × weight) + current_requests                                                                                                          
                                                                                                                                                                        
if estimated ≥ limit → HTTP 429 
```

{% endcode %}

**Example:** The previous segment ended with 60 requests and the current one has 25, at 15 seconds into the segment:

{% code lineNumbers="true" %}

```java
weight    = 1 - (15 / 30) = 0.5                                                                                                                                       
estimated = (60 × 0.5) + 25 = 55 → Allowed (< 70)
```

{% endcode %}

#### Response Headers

Every API response includes rate limiting headers so you can monitor your usage:

<table><thead><tr><th>Header</th><th width="373.6328125">Description</th><th width="145.015625">Example</th></tr></thead><tbody><tr><td><code>x-rate-limit-limit</code></td><td><code>Maximum requests per window</code></td><td><code>70</code></td></tr><tr><td><code>x-rate-limit-remaining</code></td><td><code>Remaining requests in current window</code> </td><td><code>45</code></td></tr><tr><td><code>x-rate-limit-reset</code></td><td><code>Unix timestamp when the window resets</code></td><td><code>1742121660</code></td></tr></tbody></table>

When the limit is exceeded, the API responds with HTTP 429 Too Many Requests and includes:

<table><thead><tr><th>Header</th><th width="373.6328125">Description</th><th width="145.015625">Example</th></tr></thead><tbody><tr><td><code>Retry-After</code> </td><td><code>Seconds to wait before retrying</code></td><td><code>18</code></td></tr></tbody></table>

**Example Responses:**

{% tabs %}
{% tab title="Normal Response" %}
`HTTP/1.1 200 OK x-rate-limit-limit: 70 x-rate-limit-remaining: 45 x-rate-limit-reset: 1742121660`
{% endtab %}

{% tab title="Rate Limited Response" %} <sup>`HTTP/1.1 429 Too Many Requests x-rate-limit-limit: 70 x-rate-limit-remaining: 0 x-rate-limit-reset: 1742121660 Retry-After: 18`</sup>

<sup>`{"payload": [], "message": "too many request", "code": "too_many_request"}`</sup>
{% endtab %}
{% endtabs %}

#### Best Practices

* Monitor headers: Check x-rate-limit-remaining on each response to track your usage before hitting the limit.
* Retry with backoff: When you receive a 429, wait the number of seconds indicated in the Retry-After header before retrying.
* Distribute requests: Spread your calls evenly over time instead of sending bursts.
* Use pagination efficiently: Use higher limit values (e.g., ?limit=100) to reduce the number of requests needed.

If you need a higher rate limit, please contact your account manager or our support team.

#### Examples

{% tabs %}
{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
import requests
import time                                                                                                                                                          

BASE_URL = "https://api.woowup.com/apiv3"                                                                                                                            
API_TOKEN = "your_api_token"                                       
                                          
headers = {                                                                                                                                                          
  "Authorization": f"Bearer {API_TOKEN}",
  "Accept": "application/json"                                                                                                                                     
}                                                                  
                                                                                                                                                                   
def make_request(endpoint):                                        
  response = requests.get(f"{BASE_URL}/{endpoint}", headers=headers)

  # Read rate limit headers                                                                                                                                        
  limit = response.headers.get("x-rate-limit-limit")
  remaining = response.headers.get("x-rate-limit-remaining")                                                                                                       
  reset = response.headers.get("x-rate-limit-reset")                                                                                                               
                                          
  print(f"Limit: {limit}, Remaining: {remaining}, Reset: {reset}")                                                                                                 
                                                                 
  if response.status_code == 429:                                                                                                                                  
      retry_after = int(response.headers.get("Retry-After", 30))
      print(f"Rate limited. Retrying in {retry_after}s...")                                                                                                        
      time.sleep(retry_after)                                    
      return make_request(endpoint)
                                                                                                                                                                   
  return response.json()              
                                                                                                                                                                   
result = make_request("/users") 
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (Node.js)" %}
{% code lineNumbers="true" %}

```typescript
const BASE_URL = "https://api.woowup.com/apiv3";
const API_TOKEN = "your_api_token";         
                                        
async function makeRequest(endpoint) {
  const response = await fetch(`${BASE_URL}/${endpoint}`, {                                                                                                          
    headers: {                              
      Authorization: `Bearer ${API_TOKEN}`,                                                                                                                          
      Accept: "application/json",                                  
    },                                                                                                                                                               
  });
                                                                                                                                                                     
  // Read rate limit headers                                       
  const limit = response.headers.get("x-rate-limit-limit");
  const remaining = response.headers.get("x-rate-limit-remaining");
  const reset = response.headers.get("x-rate-limit-reset");

  console.log(`Limit: ${limit}, Remaining: ${remaining}, Reset: ${reset}`);                                                                                          
                                        
  if (response.status === 429) {                                                                                                                                     
    const retryAfter = parseInt(response.headers.get("Retry-After") || "30", 10);                                                                                    
    console.log(`Rate limited. Retrying in ${retryAfter}s...`);
    await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));                                                                                          
    return makeRequest(endpoint);                                  
  }
                                                                                                                                                                     
  return response.json();
}                                                                                                                                                                    
                                                                   
makeRequest("/users").then(console.log);
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
require "net/http"                                                                                                                                                   
require "json"
require "uri"                                                                                                                                                        
                                                                   
BASE_URL = "https://api.woowup.com/apiv3"   
API_TOKEN = "your_api_token"            

def make_request(endpoint)                                                                                                                                           
  uri = URI("#{BASE_URL}/#{endpoint}")
  request = Net::HTTP::Get.new(uri)                                                                                                                                  
  request["Authorization"] = "Bearer #{API_TOKEN}"                 
  request["Accept"] = "application/json"

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|                                                                                        
    http.request(request)               
  end                                                                                                                                                                
                                                                                                                                                                     
  # Read rate limit headers
  limit = response["x-rate-limit-limit"]                                                                                                                             
  remaining = response["x-rate-limit-remaining"]                   
  reset = response["x-rate-limit-reset"]
                                            
  puts "Limit: #{limit}, Remaining: #{remaining}, Reset: #{reset}"

  if response.code.to_i == 429                                                                                                                                       
    retry_after = (response["Retry-After"] || "30").to_i
    puts "Rate limited. Retrying in #{retry_after}s..."                                                                                                              
    sleep(retry_after)                                             
    return make_request(endpoint)
  end                                                                                                                                                                
 
  JSON.parse(response.body)                                                                                                                                          
end                                                                

result = make_request("users")   
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
<?php
                                                                                                                                                                   
$baseUrl = 'https://api.woowup.com/apiv3';                         
$apiToken = 'your_api_token';           

function makeRequest($endpoint) {                                                                                                                                    
  global $baseUrl, $apiToken;
                                                                                                                                                                   
  $ch = curl_init("{$baseUrl}/{$endpoint}");                     
  curl_setopt_array($ch, [            
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HEADERFUNCTION => function ($ch, $header) use (&$headers) {                                                                                          
          $parts = explode(':', $header, 2);
          if (count($parts) === 2) {                                                                                                                               
              $headers[strtolower(trim($parts[0]))] = trim($parts[1]);
          }                                                                                                                                                        
          return strlen($header);     
      },                                                                                                                                                           
      CURLOPT_HTTPHEADER => [                                                                                                                                      
          "Authorization: Bearer {$apiToken}",
          "Accept: application/json",                                                                                                                              
      ],                                                         
  ]);
                                                                                                                                                                   
  $headers = [];
  $body = curl_exec($ch);                                                                                                                                          
  $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);           
  curl_close($ch);                        
                                      
  // Read rate limit headers
  $limit = $headers['x-rate-limit-limit'] ?? 'N/A';                                                                                                                
  $remaining = $headers['x-rate-limit-remaining'] ?? 'N/A';
  $reset = $headers['x-rate-limit-reset'] ?? 'N/A';                                                                                                                
                                                                 
  echo "Limit: {$limit}, Remaining: {$remaining}, Reset: {$reset}\n";                                                                                              

  if ($statusCode === 429) {                                                                                                                                       
      $retryAfter = (int) ($headers['retry-after'] ?? 30);       
      echo "Rate limited. Retrying in {$retryAfter}s...\n";                                                                                                        
      sleep($retryAfter);                                        
      return makeRequest($endpoint);
  }                                                                                                                                                                
                                      
  return json_decode($body, true);                                                                                                                                 
}                                                                                                                                                                    

$result = makeRequest('/users');                                                                                                                                     
                               
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Authentication <a href="#authentication" id="authentication"></a>

In any call to the API you must sent the apikey in the query string as a parameter.

For example, if your apikey is 'abcdefghijklmnopqrstuvwxyz', you should do a request to

`https://api.woowup.com/apiv3/users?apikey=abcdefghijklmnopqrstuvwxyz`

Other method, and the recomended, is via Authentication Header, in every call you must send the header

`Authorization: Basic abcdefghijklmnopqrstuvwxyz`&#x20;

#### Deleted accounts

Requests from deleted accounts receive `410 Gone` with code `account_deleted`. Once an account has been deactivated, its API key is no longer valid and all requests will\
be rejected.

{% code lineNumbers="true" %}

```json
{
    "payload": [],
    "message": "gone: account deleted",
    "code": "account_deleted"
}
```

{% endcode %}

### Pagination <a href="#pagination" id="pagination"></a>

When you are doing a search, we paginate the results. In all paginated endpoints the pagination's parameters are:

| Parameter | Description                         | Default |
| --------- | ----------------------------------- | ------- |
| limit     | Items per page returned. Max: 100   | 25      |
| page      | Number of the page. First page is 0 | 0       |

### Returned format <a href="#returned-format" id="returned-format"></a>

All endpoints return data in json format, with the `Content-Type: application/json` header. For a correct use you have to send in all the requests the header `Accept: application/json`.

### How to encode 'service\_uid' <a href="#how-to-encode-service_uid" id="how-to-encode-service_uid"></a>

When you are trying to find an user you could identificate this by his id or his service\_uid (commonly is the email), when you use the service\_uid you must encode this in Base64 en the result encode as url safe, for example if you need to do this in php:

```php
<?php

$service_uid = 'example@email.com';
$encoded_uid = urlencode(base64_encode($service_uid));
$url = 'https://api.woowup.com/apiv3/users/'.$encoded_uid.'/exist';

```

### Sample Code: How to start sending us your purchase orders <a href="#sample-code-how-to-start-sending-us-your-purchase-orders" id="sample-code-how-to-start-sending-us-your-purchase-orders"></a>

In the following link you will find a fully functional example in PHP that process a CSV file with orders and customers and use the API to send them to WoowUp: [Download example](https://github.com/woowup/woowup-php-client/blob/master/dist/woowup-php-client-v1.zip)

### Support <a href="#support" id="support"></a>

**Remember to contact us on** [**developers@woowup.com**](mailto:developers@woowup.com) **for any questions, we will be happy to assist you.**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://woowup-docs.gitbook.io/woowup-developer-docs/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
