REST API v1

Documentación API

Accede a tus pedidos y datos de apartamentos colombianos de forma programática. Autenticación por API key, respuestas JSON, paginación por página.

Quick Start

La API de DataForest es una API REST que devuelve datos en formato JSON. La URL base para todos los endpoints es:

https://dataforest.io/api/v1

Tu primera solicitud — verifica que la API esté disponible:

curl https://dataforest.io/api/v1/health
const res = await fetch('https://dataforest.io/api/v1/health');
const data = await res.json();
console.log(data);
import requests

res = requests.get('https://dataforest.io/api/v1/health')
data = res.json()
print(data)
<?php
$res = file_get_contents('https://dataforest.io/api/v1/health');
$data = json_decode($res, true);
print_r($data);
require 'net/http'
require 'json'

uri = URI('https://dataforest.io/api/v1/health')
data = JSON.parse(Net::HTTP.get(uri))
puts data
resp, _ := http.Get("https://dataforest.io/api/v1/health")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
using var client = new HttpClient();
var json = await client.GetStringAsync("https://dataforest.io/api/v1/health");
Console.WriteLine(json);

Respuesta:

{
  "status": "ok",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "version": "1.0.0"
}

Autenticación

Todos los endpoints (excepto /health) requieren autenticación mediante un parámetro api_key en la URL.

curl "https://dataforest.io/api/v1/orders?api_key=YOUR_API_KEY"
const res = await fetch('https://dataforest.io/api/v1/orders?api_key=YOUR_API_KEY');
const data = await res.json();
import requests

res = requests.get('https://dataforest.io/api/v1/orders',
    params={'api_key': 'YOUR_API_KEY'})
data = res.json()
<?php
$res = file_get_contents('https://dataforest.io/api/v1/orders?api_key=YOUR_API_KEY');
$data = json_decode($res, true);
require 'net/http'
require 'json'

uri = URI('https://dataforest.io/api/v1/orders?api_key=YOUR_API_KEY')
data = JSON.parse(Net::HTTP.get(uri))
resp, _ := http.Get("https://dataforest.io/api/v1/orders?api_key=YOUR_API_KEY")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
using var client = new HttpClient();
var json = await client.GetStringAsync("https://dataforest.io/api/v1/orders?api_key=YOUR_API_KEY");

Cómo funciona

  • Tu api_key es una clave única generada desde tu panel de API.
  • Genérala y adminístrala desde tu panel de API.
  • Solo puedes consultar datos de pedidos que has pagado. El API key está vinculado a tu cuenta y tus compras.
⚠️
Importante: Mantén tu API key en secreto. No la expongas en código del lado del cliente ni en repositorios públicos.

Rate Limiting

La API tiene un límite de 120 solicitudes por ventana de 60 segundos por API key.

Header Descripción
x-ratelimit-limit Límite máximo de solicitudes en la ventana
x-ratelimit-remaining Solicitudes restantes en la ventana actual
x-request-id ID único de la solicitud (para soporte/debugging)

Si excedes el límite, recibirás un 429:

{
  "error": "Rate limit exceeded",
  "message": "Too many requests, please try again later",
  "retry_after": 45
}

Paginación

La API usa paginación basada en página. Usa el parámetro page para navegar entre páginas. Cuando has_more sea false, has llegado al final de los resultados.

Ejemplo de flujo

Primera solicitud:

curl "https://dataforest.io/api/v1/orders?api_key=KEY&limit=20"
const res = await fetch('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20');
const data = await res.json();
console.log(data.has_more);
import requests

res = requests.get('https://dataforest.io/api/v1/orders',
    params={'api_key': 'KEY', 'limit': 20})
data = res.json()
print(data['has_more'])
<?php
$res = file_get_contents('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20');
$data = json_decode($res, true);
echo $data['has_more'];
require 'net/http'
require 'json'

uri = URI('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20')
data = JSON.parse(Net::HTTP.get(uri))
puts data['has_more']
resp, _ := http.Get("https://dataforest.io/api/v1/orders?api_key=KEY&limit=20")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
using var client = new HttpClient();
var json = await client.GetStringAsync("https://dataforest.io/api/v1/orders?api_key=KEY&limit=20");
Console.WriteLine(json);

Respuesta (parcial):

{
  "data": [...],
  "has_more": true,
  "count": 20
}

Siguiente página:

curl "https://dataforest.io/api/v1/orders?api_key=KEY&limit=20&page=2"
const next = await fetch('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20&page=2');
const page2 = await next.json();
next_res = requests.get('https://dataforest.io/api/v1/orders',
    params={'api_key': 'KEY', 'limit': 20, 'page': 2})
page2 = next_res.json()
$next = file_get_contents('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20&page=2');
$page2 = json_decode($next, true);
uri = URI('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20&page=2')
page2 = JSON.parse(Net::HTTP.get(uri))
resp, _ := http.Get("https://dataforest.io/api/v1/orders?api_key=KEY&limit=20&page=2")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var json = await client.GetStringAsync("https://dataforest.io/api/v1/orders?api_key=KEY&limit=20&page=2");

Cuando has_more sea false, has llegado al final de los resultados.

Errores

La API usa códigos HTTP estándar. Todas las respuestas de error siguen este formato:

{
  "error": "Not Found",
  "message": "Line item not found"
}

Códigos de estado

Código Significado
200 Solicitud exitosa
400 Parámetros inválidos o faltantes
401 API key inválida o faltante
403 No tienes acceso al recurso solicitado
404 Recurso no encontrado
429 Límite de solicitudes excedido
500 Error interno del servidor
GET

/health

Verifica el estado de la API. No requiere autenticación.

Solicitud

curl https://dataforest.io/api/v1/health
const res = await fetch('https://dataforest.io/api/v1/health');
const data = await res.json();
import requests

res = requests.get('https://dataforest.io/api/v1/health')
data = res.json()
<?php
$res = file_get_contents('https://dataforest.io/api/v1/health');
$data = json_decode($res, true);
require 'net/http'
require 'json'

uri = URI('https://dataforest.io/api/v1/health')
data = JSON.parse(Net::HTTP.get(uri))
resp, _ := http.Get("https://dataforest.io/api/v1/health")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
using var client = new HttpClient();
var json = await client.GetStringAsync("https://dataforest.io/api/v1/health");

Respuesta 200

{
  "status": "ok",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "version": "1.0.0"
}
GET

/orders

Obtiene tus pedidos pagados con sus line items. Cada line item representa un edificio comprado e incluye el ID necesario para consultar sus unidades.

Parámetros

Parámetro Tipo Requerido Descripción
api_key string Tu clave de API
limit integer No Resultados por página (default: 20, max: 50)
page integer No Página de resultados (default: 1)

Solicitud

curl "https://dataforest.io/api/v1/orders?api_key=KEY&limit=20"
const res = await fetch('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20');
const data = await res.json();
console.log(data);
import requests

res = requests.get('https://dataforest.io/api/v1/orders',
    params={'api_key': 'KEY', 'limit': 20})
data = res.json()
print(data)
<?php
$res = file_get_contents('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20');
$data = json_decode($res, true);
print_r($data);
require 'net/http'
require 'json'

uri = URI('https://dataforest.io/api/v1/orders?api_key=KEY&limit=20')
data = JSON.parse(Net::HTTP.get(uri))
puts data
resp, _ := http.Get("https://dataforest.io/api/v1/orders?api_key=KEY&limit=20")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
using var client = new HttpClient();
var json = await client.GetStringAsync("https://dataforest.io/api/v1/orders?api_key=KEY&limit=20");
Console.WriteLine(json);

Respuesta 200

{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "paid",
      "amount": 150000,
      "order_date": "2025-01-15T10:30:00.000Z",
      "line_items": [
        {
          "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
          "apartment_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
          "apartment_name": "Torres del Parque",
          "unit_count": 120
        }
      ]
    }
  ],
  "has_more": false,
  "count": 1
}
GET

/units/:id

Obtiene las unidades individuales de un edificio comprado. El :id es el id de un line item obtenido de /orders.

Parámetros

Parámetro Tipo Requerido Descripción
:id string (UUID) UUID del line item (de /orders)
api_key string Tu clave de API
limit integer No Resultados por página (default: 50, max: 100)
page integer No Página de resultados (default: 1)

Solicitud

curl "https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012?api_key=KEY&limit=50"
const res = await fetch('https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012?api_key=KEY&limit=50');
const data = await res.json();
console.log(data);
import requests

res = requests.get('https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012',
    params={'api_key': 'KEY', 'limit': 50})
data = res.json()
print(data)
<?php
$res = file_get_contents('https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012?api_key=KEY&limit=50');
$data = json_decode($res, true);
print_r($data);
require 'net/http'
require 'json'

uri = URI('https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012?api_key=KEY&limit=50')
data = JSON.parse(Net::HTTP.get(uri))
puts data
resp, _ := http.Get("https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012?api_key=KEY&limit=50")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
using var client = new HttpClient();
var json = await client.GetStringAsync("https://dataforest.io/api/v1/units/d4e5f6a7-b8c9-0123-4567-890abcdef012?api_key=KEY&limit=50");
Console.WriteLine(json);

Respuesta 200

{
  "data": [
    {
      "id": "f8a9b0c1-d2e3-4567-890a-bcdef1234567",
      "apartment_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "apartment_name": "Torres del Parque",
      "unit_number": "Apt 301",
      "address": "Calle 36 #5-80 Apt 301",
      "city": "medellin"
    }
  ],
  "has_more": true,
  "count": 1
}
💡
Tip: Primero consulta /orders para obtener los IDs de line items. Luego usa cada line_item.id para consultar las unidades de ese edificio.