curl --request POST \
--url https://api.tiendadepuntos.com/external/tags/add \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"client": {
"email": "juanma@mailinator.com",
"dni": "40100800",
"first_name": "Juan Manuel",
"last_name": "Pérez",
"phone": "+541164593678",
"birthday": "1990-01-01T00:00:00.000Z",
"gender": 0
},
"amount": 50,
"pointItems": [
12,
12,
37
],
"branch_id": 1972,
"external_id": "FAC-A-0001-00012345",
"reason": "Suma por compra de 2 medialunas y un cafe latte",
"giftCards": [
{
"clientMail": "exampleMail@tiendadepuntos.com",
"points": {
"selectedRewardType": "points",
"amount": 50,
"pointItemsIds": [
123
],
"pointsToGive": 100,
"reason": "Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50"
},
"applyBonus": {
"applyLevelPointsBonus": true,
"applyPointRulesBonus": true
}
}
],
"ignoreCreateClient": false,
"origin": "external-integration",
"extra_data": "[{\"ArticuloDetalle\":\"Remera negra\",\"Cantidad\":3,\"Talle\":\"M\"}]"
}
'import requests
url = "https://api.tiendadepuntos.com/external/tags/add"
payload = {
"client": {
"email": "juanma@mailinator.com",
"dni": "40100800",
"first_name": "Juan Manuel",
"last_name": "Pérez",
"phone": "+541164593678",
"birthday": "1990-01-01T00:00:00.000Z",
"gender": 0
},
"amount": 50,
"pointItems": [12, 12, 37],
"branch_id": 1972,
"external_id": "FAC-A-0001-00012345",
"reason": "Suma por compra de 2 medialunas y un cafe latte",
"giftCards": [
{
"clientMail": "exampleMail@tiendadepuntos.com",
"points": {
"selectedRewardType": "points",
"amount": 50,
"pointItemsIds": [123],
"pointsToGive": 100,
"reason": "Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50"
},
"applyBonus": {
"applyLevelPointsBonus": True,
"applyPointRulesBonus": True
}
}
],
"ignoreCreateClient": False,
"origin": "external-integration",
"extra_data": "[{\"ArticuloDetalle\":\"Remera negra\",\"Cantidad\":3,\"Talle\":\"M\"}]"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
client: {
email: 'juanma@mailinator.com',
dni: '40100800',
first_name: 'Juan Manuel',
last_name: 'Pérez',
phone: '+541164593678',
birthday: '1990-01-01T00:00:00.000Z',
gender: 0
},
amount: 50,
pointItems: [12, 12, 37],
branch_id: 1972,
external_id: 'FAC-A-0001-00012345',
reason: 'Suma por compra de 2 medialunas y un cafe latte',
giftCards: [
{
clientMail: 'exampleMail@tiendadepuntos.com',
points: {
selectedRewardType: 'points',
amount: 50,
pointItemsIds: [123],
pointsToGive: 100,
reason: 'Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50'
},
applyBonus: {applyLevelPointsBonus: true, applyPointRulesBonus: true}
}
],
ignoreCreateClient: false,
origin: 'external-integration',
extra_data: '[{"ArticuloDetalle":"Remera negra","Cantidad":3,"Talle":"M"}]'
})
};
fetch('https://api.tiendadepuntos.com/external/tags/add', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tiendadepuntos.com/external/tags/add",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'client' => [
'email' => 'juanma@mailinator.com',
'dni' => '40100800',
'first_name' => 'Juan Manuel',
'last_name' => 'Pérez',
'phone' => '+541164593678',
'birthday' => '1990-01-01T00:00:00.000Z',
'gender' => 0
],
'amount' => 50,
'pointItems' => [
12,
12,
37
],
'branch_id' => 1972,
'external_id' => 'FAC-A-0001-00012345',
'reason' => 'Suma por compra de 2 medialunas y un cafe latte',
'giftCards' => [
[
'clientMail' => 'exampleMail@tiendadepuntos.com',
'points' => [
'selectedRewardType' => 'points',
'amount' => 50,
'pointItemsIds' => [
123
],
'pointsToGive' => 100,
'reason' => 'Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50'
],
'applyBonus' => [
'applyLevelPointsBonus' => true,
'applyPointRulesBonus' => true
]
]
],
'ignoreCreateClient' => false,
'origin' => 'external-integration',
'extra_data' => '[{"ArticuloDetalle":"Remera negra","Cantidad":3,"Talle":"M"}]'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.tiendadepuntos.com/external/tags/add"
payload := strings.NewReader("{\n \"client\": {\n \"email\": \"juanma@mailinator.com\",\n \"dni\": \"40100800\",\n \"first_name\": \"Juan Manuel\",\n \"last_name\": \"Pérez\",\n \"phone\": \"+541164593678\",\n \"birthday\": \"1990-01-01T00:00:00.000Z\",\n \"gender\": 0\n },\n \"amount\": 50,\n \"pointItems\": [\n 12,\n 12,\n 37\n ],\n \"branch_id\": 1972,\n \"external_id\": \"FAC-A-0001-00012345\",\n \"reason\": \"Suma por compra de 2 medialunas y un cafe latte\",\n \"giftCards\": [\n {\n \"clientMail\": \"exampleMail@tiendadepuntos.com\",\n \"points\": {\n \"selectedRewardType\": \"points\",\n \"amount\": 50,\n \"pointItemsIds\": [\n 123\n ],\n \"pointsToGive\": 100,\n \"reason\": \"Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50\"\n },\n \"applyBonus\": {\n \"applyLevelPointsBonus\": true,\n \"applyPointRulesBonus\": true\n }\n }\n ],\n \"ignoreCreateClient\": false,\n \"origin\": \"external-integration\",\n \"extra_data\": \"[{\\\"ArticuloDetalle\\\":\\\"Remera negra\\\",\\\"Cantidad\\\":3,\\\"Talle\\\":\\\"M\\\"}]\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.tiendadepuntos.com/external/tags/add")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"client\": {\n \"email\": \"juanma@mailinator.com\",\n \"dni\": \"40100800\",\n \"first_name\": \"Juan Manuel\",\n \"last_name\": \"Pérez\",\n \"phone\": \"+541164593678\",\n \"birthday\": \"1990-01-01T00:00:00.000Z\",\n \"gender\": 0\n },\n \"amount\": 50,\n \"pointItems\": [\n 12,\n 12,\n 37\n ],\n \"branch_id\": 1972,\n \"external_id\": \"FAC-A-0001-00012345\",\n \"reason\": \"Suma por compra de 2 medialunas y un cafe latte\",\n \"giftCards\": [\n {\n \"clientMail\": \"exampleMail@tiendadepuntos.com\",\n \"points\": {\n \"selectedRewardType\": \"points\",\n \"amount\": 50,\n \"pointItemsIds\": [\n 123\n ],\n \"pointsToGive\": 100,\n \"reason\": \"Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50\"\n },\n \"applyBonus\": {\n \"applyLevelPointsBonus\": true,\n \"applyPointRulesBonus\": true\n }\n }\n ],\n \"ignoreCreateClient\": false,\n \"origin\": \"external-integration\",\n \"extra_data\": \"[{\\\"ArticuloDetalle\\\":\\\"Remera negra\\\",\\\"Cantidad\\\":3,\\\"Talle\\\":\\\"M\\\"}]\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tiendadepuntos.com/external/tags/add")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"client\": {\n \"email\": \"juanma@mailinator.com\",\n \"dni\": \"40100800\",\n \"first_name\": \"Juan Manuel\",\n \"last_name\": \"Pérez\",\n \"phone\": \"+541164593678\",\n \"birthday\": \"1990-01-01T00:00:00.000Z\",\n \"gender\": 0\n },\n \"amount\": 50,\n \"pointItems\": [\n 12,\n 12,\n 37\n ],\n \"branch_id\": 1972,\n \"external_id\": \"FAC-A-0001-00012345\",\n \"reason\": \"Suma por compra de 2 medialunas y un cafe latte\",\n \"giftCards\": [\n {\n \"clientMail\": \"exampleMail@tiendadepuntos.com\",\n \"points\": {\n \"selectedRewardType\": \"points\",\n \"amount\": 50,\n \"pointItemsIds\": [\n 123\n ],\n \"pointsToGive\": 100,\n \"reason\": \"Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50\"\n },\n \"applyBonus\": {\n \"applyLevelPointsBonus\": true,\n \"applyPointRulesBonus\": true\n }\n }\n ],\n \"ignoreCreateClient\": false,\n \"origin\": \"external-integration\",\n \"extra_data\": \"[{\\\"ArticuloDetalle\\\":\\\"Remera negra\\\",\\\"Cantidad\\\":3,\\\"Talle\\\":\\\"M\\\"}]\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 201,
"message": "Request was successful",
"data": {
"pointOperationId": 998877,
"clientId": 84213,
"points": {
"amount": 50,
"totalPointsToGive": 55,
"initialPointsToGive": 50
}
}
}{
"statusCode": 400,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Los ítems enviados no suman puntos. Revisá la configuración de puntos y montos de los ítems.",
"errors": [
{}
],
"data": {}
}{
"statusCode": 401,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Api key is invalid",
"errors": [
{}
],
"data": {}
}{
"statusCode": 403,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Branch with id 1972 does not belong to business with id 42",
"errors": [
{}
],
"data": {}
}{
"statusCode": 404,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "PointsItem with id 12 not found",
"errors": [
{}
],
"data": {}
}{
"statusCode": 409,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Ya existe una operación de puntos con el externalId FAC-A-0001-00012345 para este negocio",
"errors": [
{}
],
"data": {}
}{
"statusCode": 503,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "No se pudo procesar la suma en este momento. Reintentá en unos segundos.",
"errors": [
{}
],
"data": {}
}Sumar puntos a un cliente por una compra
Acredita puntos de forma inmediata a partir del monto de una compra. Es el endpoint principal para integrar un POS o ERP.
El cliente se identifica por email o dni. Si no existe, se crea automáticamente, salvo que se mande ignoreCreateClient: true.
Idempotencia: mandá siempre external_id con el identificador de la venta en tu sistema (número de factura, id de ticket). Si llega un external_id que ya tiene una operación activa, la API responde 409 en vez de duplicar los puntos. Ese mismo external_id es el que se usa para cancelar la operación después.
Sumar por ítems (pointItems): en vez del monto podés mandar los ids de los ítems de puntos del catálogo del comercio. Repetí el mismo id para cargar más de una unidad del ítem (tope de 100 ids). Si viene pointItems, el amount del body se ignora y el amount de la respuesta es la suma de los montos de los ítems; points.selectedRewardType pasa a items. Las bonificaciones de nivel y las reglas de puntos se siguen aplicando igual que en la suma por monto.
curl --request POST \
--url https://api.tiendadepuntos.com/external/tags/add \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"client": {
"email": "juanma@mailinator.com",
"dni": "40100800",
"first_name": "Juan Manuel",
"last_name": "Pérez",
"phone": "+541164593678",
"birthday": "1990-01-01T00:00:00.000Z",
"gender": 0
},
"amount": 50,
"pointItems": [
12,
12,
37
],
"branch_id": 1972,
"external_id": "FAC-A-0001-00012345",
"reason": "Suma por compra de 2 medialunas y un cafe latte",
"giftCards": [
{
"clientMail": "exampleMail@tiendadepuntos.com",
"points": {
"selectedRewardType": "points",
"amount": 50,
"pointItemsIds": [
123
],
"pointsToGive": 100,
"reason": "Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50"
},
"applyBonus": {
"applyLevelPointsBonus": true,
"applyPointRulesBonus": true
}
}
],
"ignoreCreateClient": false,
"origin": "external-integration",
"extra_data": "[{\"ArticuloDetalle\":\"Remera negra\",\"Cantidad\":3,\"Talle\":\"M\"}]"
}
'import requests
url = "https://api.tiendadepuntos.com/external/tags/add"
payload = {
"client": {
"email": "juanma@mailinator.com",
"dni": "40100800",
"first_name": "Juan Manuel",
"last_name": "Pérez",
"phone": "+541164593678",
"birthday": "1990-01-01T00:00:00.000Z",
"gender": 0
},
"amount": 50,
"pointItems": [12, 12, 37],
"branch_id": 1972,
"external_id": "FAC-A-0001-00012345",
"reason": "Suma por compra de 2 medialunas y un cafe latte",
"giftCards": [
{
"clientMail": "exampleMail@tiendadepuntos.com",
"points": {
"selectedRewardType": "points",
"amount": 50,
"pointItemsIds": [123],
"pointsToGive": 100,
"reason": "Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50"
},
"applyBonus": {
"applyLevelPointsBonus": True,
"applyPointRulesBonus": True
}
}
],
"ignoreCreateClient": False,
"origin": "external-integration",
"extra_data": "[{\"ArticuloDetalle\":\"Remera negra\",\"Cantidad\":3,\"Talle\":\"M\"}]"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
client: {
email: 'juanma@mailinator.com',
dni: '40100800',
first_name: 'Juan Manuel',
last_name: 'Pérez',
phone: '+541164593678',
birthday: '1990-01-01T00:00:00.000Z',
gender: 0
},
amount: 50,
pointItems: [12, 12, 37],
branch_id: 1972,
external_id: 'FAC-A-0001-00012345',
reason: 'Suma por compra de 2 medialunas y un cafe latte',
giftCards: [
{
clientMail: 'exampleMail@tiendadepuntos.com',
points: {
selectedRewardType: 'points',
amount: 50,
pointItemsIds: [123],
pointsToGive: 100,
reason: 'Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50'
},
applyBonus: {applyLevelPointsBonus: true, applyPointRulesBonus: true}
}
],
ignoreCreateClient: false,
origin: 'external-integration',
extra_data: '[{"ArticuloDetalle":"Remera negra","Cantidad":3,"Talle":"M"}]'
})
};
fetch('https://api.tiendadepuntos.com/external/tags/add', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tiendadepuntos.com/external/tags/add",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'client' => [
'email' => 'juanma@mailinator.com',
'dni' => '40100800',
'first_name' => 'Juan Manuel',
'last_name' => 'Pérez',
'phone' => '+541164593678',
'birthday' => '1990-01-01T00:00:00.000Z',
'gender' => 0
],
'amount' => 50,
'pointItems' => [
12,
12,
37
],
'branch_id' => 1972,
'external_id' => 'FAC-A-0001-00012345',
'reason' => 'Suma por compra de 2 medialunas y un cafe latte',
'giftCards' => [
[
'clientMail' => 'exampleMail@tiendadepuntos.com',
'points' => [
'selectedRewardType' => 'points',
'amount' => 50,
'pointItemsIds' => [
123
],
'pointsToGive' => 100,
'reason' => 'Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50'
],
'applyBonus' => [
'applyLevelPointsBonus' => true,
'applyPointRulesBonus' => true
]
]
],
'ignoreCreateClient' => false,
'origin' => 'external-integration',
'extra_data' => '[{"ArticuloDetalle":"Remera negra","Cantidad":3,"Talle":"M"}]'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.tiendadepuntos.com/external/tags/add"
payload := strings.NewReader("{\n \"client\": {\n \"email\": \"juanma@mailinator.com\",\n \"dni\": \"40100800\",\n \"first_name\": \"Juan Manuel\",\n \"last_name\": \"Pérez\",\n \"phone\": \"+541164593678\",\n \"birthday\": \"1990-01-01T00:00:00.000Z\",\n \"gender\": 0\n },\n \"amount\": 50,\n \"pointItems\": [\n 12,\n 12,\n 37\n ],\n \"branch_id\": 1972,\n \"external_id\": \"FAC-A-0001-00012345\",\n \"reason\": \"Suma por compra de 2 medialunas y un cafe latte\",\n \"giftCards\": [\n {\n \"clientMail\": \"exampleMail@tiendadepuntos.com\",\n \"points\": {\n \"selectedRewardType\": \"points\",\n \"amount\": 50,\n \"pointItemsIds\": [\n 123\n ],\n \"pointsToGive\": 100,\n \"reason\": \"Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50\"\n },\n \"applyBonus\": {\n \"applyLevelPointsBonus\": true,\n \"applyPointRulesBonus\": true\n }\n }\n ],\n \"ignoreCreateClient\": false,\n \"origin\": \"external-integration\",\n \"extra_data\": \"[{\\\"ArticuloDetalle\\\":\\\"Remera negra\\\",\\\"Cantidad\\\":3,\\\"Talle\\\":\\\"M\\\"}]\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.tiendadepuntos.com/external/tags/add")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"client\": {\n \"email\": \"juanma@mailinator.com\",\n \"dni\": \"40100800\",\n \"first_name\": \"Juan Manuel\",\n \"last_name\": \"Pérez\",\n \"phone\": \"+541164593678\",\n \"birthday\": \"1990-01-01T00:00:00.000Z\",\n \"gender\": 0\n },\n \"amount\": 50,\n \"pointItems\": [\n 12,\n 12,\n 37\n ],\n \"branch_id\": 1972,\n \"external_id\": \"FAC-A-0001-00012345\",\n \"reason\": \"Suma por compra de 2 medialunas y un cafe latte\",\n \"giftCards\": [\n {\n \"clientMail\": \"exampleMail@tiendadepuntos.com\",\n \"points\": {\n \"selectedRewardType\": \"points\",\n \"amount\": 50,\n \"pointItemsIds\": [\n 123\n ],\n \"pointsToGive\": 100,\n \"reason\": \"Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50\"\n },\n \"applyBonus\": {\n \"applyLevelPointsBonus\": true,\n \"applyPointRulesBonus\": true\n }\n }\n ],\n \"ignoreCreateClient\": false,\n \"origin\": \"external-integration\",\n \"extra_data\": \"[{\\\"ArticuloDetalle\\\":\\\"Remera negra\\\",\\\"Cantidad\\\":3,\\\"Talle\\\":\\\"M\\\"}]\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tiendadepuntos.com/external/tags/add")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"client\": {\n \"email\": \"juanma@mailinator.com\",\n \"dni\": \"40100800\",\n \"first_name\": \"Juan Manuel\",\n \"last_name\": \"Pérez\",\n \"phone\": \"+541164593678\",\n \"birthday\": \"1990-01-01T00:00:00.000Z\",\n \"gender\": 0\n },\n \"amount\": 50,\n \"pointItems\": [\n 12,\n 12,\n 37\n ],\n \"branch_id\": 1972,\n \"external_id\": \"FAC-A-0001-00012345\",\n \"reason\": \"Suma por compra de 2 medialunas y un cafe latte\",\n \"giftCards\": [\n {\n \"clientMail\": \"exampleMail@tiendadepuntos.com\",\n \"points\": {\n \"selectedRewardType\": \"points\",\n \"amount\": 50,\n \"pointItemsIds\": [\n 123\n ],\n \"pointsToGive\": 100,\n \"reason\": \"Se entregan 500 puntos por comprar un cafe cuyo valor fue de $50\"\n },\n \"applyBonus\": {\n \"applyLevelPointsBonus\": true,\n \"applyPointRulesBonus\": true\n }\n }\n ],\n \"ignoreCreateClient\": false,\n \"origin\": \"external-integration\",\n \"extra_data\": \"[{\\\"ArticuloDetalle\\\":\\\"Remera negra\\\",\\\"Cantidad\\\":3,\\\"Talle\\\":\\\"M\\\"}]\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 201,
"message": "Request was successful",
"data": {
"pointOperationId": 998877,
"clientId": 84213,
"points": {
"amount": 50,
"totalPointsToGive": 55,
"initialPointsToGive": 50
}
}
}{
"statusCode": 400,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Los ítems enviados no suman puntos. Revisá la configuración de puntos y montos de los ítems.",
"errors": [
{}
],
"data": {}
}{
"statusCode": 401,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Api key is invalid",
"errors": [
{}
],
"data": {}
}{
"statusCode": 403,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Branch with id 1972 does not belong to business with id 42",
"errors": [
{}
],
"data": {}
}{
"statusCode": 404,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "PointsItem with id 12 not found",
"errors": [
{}
],
"data": {}
}{
"statusCode": 409,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "Ya existe una operación de puntos con el externalId FAC-A-0001-00012345 para este negocio",
"errors": [
{}
],
"data": {}
}{
"statusCode": 503,
"timestamp": "2026-07-31T14:05:12.431Z",
"path": "/external/tags/add",
"method": "POST",
"message": "No se pudo procesar la suma en este momento. Reintentá en unos segundos.",
"errors": [
{}
],
"data": {}
}Authorizations
API key del comercio. Se genera desde el panel de Tienda de Puntos, en Configuración → Integraciones.
Body
Datos del cliente que hizo la compra.
Show child attributes
Show child attributes
Monto de la compra en pesos. La conversión a puntos la define la regla de puntos configurada por el comercio. Se ignora si mandás pointItems. Es obligatorio salvo que vengan pointItems.
50
IDs de los ítems de puntos ya cargados en el comercio. Si viene, los puntos se calculan a partir de los ítems y amount se ignora: el monto de la operación es la suma de los montos de los ítems. Repetí el mismo id para cargar más de una unidad (máximo 100 ids).
[12, 12, 37]
Datos del operador o cajero que registró la venta.
Show child attributes
Show child attributes
ID de la sucursal donde se hizo la compra. Se obtiene de GET /external/branch. Debe pertenecer al comercio de la API key.
1972
Identificador de la transacción en tu sistema (número de factura, id de ticket). Es la clave de idempotencia: si repetís un external_id que ya tiene una operación activa, la API responde 409 en vez de duplicar los puntos. También es el identificador con el que después se cancela la operación.
"FAC-A-0001-00012345"
Observaciones de la suma de puntos.
"Suma por compra de 2 medialunas y un cafe latte"
Bonificaciones a aplicar sobre los puntos base. Si se omite, no se aplica ninguna.
Show child attributes
Show child attributes
Gift cards de regalo para otro cliente.
Show child attributes
Show child attributes
Si llega en true y el cliente no existe, la operación falla en vez de darlo de alta automáticamente.
false
Sistema desde el que se originó la operación. Se usa para trazabilidad en los reportes. Si integrás un sistema propio, usá external-integration.
external-integration, dragonfish, fudo, centum, contabilium, tiendanube, woocommerce, shopify, desktop-app, dux "external-integration"
Datos crudos de la operación en el sistema de origen, como JSON serializado. Hoy solo se persiste cuando origin es dragonfish (son los renglones de la factura, que el export de movimientos muestra en la columna "Artículos"). Para cualquier otro origen se ignora en silencio.
"[{\"ArticuloDetalle\":\"Remera negra\",\"Cantidad\":3,\"Talle\":\"M\"}]"

