Referencia de la API

Crear una vigilancia de Monitoring

POST/v1/watches

Contrato v1 / 1.0.0 62 / 2026-10-10

En esta página

Vincula una dirección a un proyecto Monitoring existente con reglas independientes. Los proyectos se crean en Account. Una dirección puede utilizarse en distintos proyectos. Repetir una vinculación idéntica no constituye una API general para actualizar reglas; utiliza Account para cambiarlas.

Permisos de la clave: watches / write / monitoring.

Cuerpo de la solicitud

CampoTipoObligatorioDescripción
projectstringNoID del proyecto. Obligatorio para listar o crear vigilancias salvo que la clave esté limitada a un proyecto. Para las demás operaciones, la omisión usa el contexto de cuenta/proyecto de la operación; indícalo explícitamente.
chainstringSíCódigo de red de GET /v1/chains.
minLength: 1
addressstringSíDirección en la red seleccionada; validada y normalizada.
minLength: 1
assetstringNoActivo predeterminado para exact: native, símbolo compatible o identificador del token.
Predeterminado: native
labelstringNoEtiqueta de la libreta de direcciones.
maxLength: 60
notestringNoNota opcional de la libreta de direcciones.
maxLength: 280
watch_outgoingbooleanNoRecibir también operaciones salientes; la red debe admitirlas.
Predeterminado: false
asset_policystringNoexact selecciona un activo; allow usa asset_ids; all selecciona todos los activos de la red. Las redes sin tokens solo admiten native/exact.
exact, allow, all; Predeterminado: exact
asset_idsstring[]NoExactamente uno para exact, al menos uno para allow y vacío para all. Con exact y una lista vacía se usa asset.
maxItems: 100
excluded_asset_idsstring[]NoActivos que se excluirán.
maxItems: 100
min_confirmationsintegerNoConfirmaciones mínimas.
Predeterminado: 0; minimum: 0
min_amountstringNoUmbral no negativo en unidades mínimas, no un importe decimal.
pattern: ^[0-9]+$
watch_contractsbooleanNoRecibir eventos de contrato compatibles.
Predeterminado: false
watch_unexpected_assetsbooleanNoRecibir eventos de activos inesperados.
Predeterminado: false
application/json
{
  "project": "1002",
  "chain": "ethereum",
  "address": "0x52908400098527886E0F7030069857D2E4169EE7",
  "asset": "native",
  "label": "Treasury"
}

Ejemplos de solicitudes

Los ejemplos realizan una operación real en tu cuenta. Configura las variables de entorno indicadas en el código. Mantén tu clave privada; las solicitudes de escritura no se reintentan automáticamente.

Shell / cURL
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
: "${CRYPTANIO_PROJECT_ID:?Set CRYPTANIO_PROJECT_ID}"
json_string() {
  local text="$1" char code index output='"'
  for ((index=0; index<${#text}; index++)); do
    char="${text:index:1}"
    case "$char" in
      '"'|'\') output+="\\$char" ;;
      *) printf -v code '%d' "'$char"
         if ((code < 32)); then printf -v char '\\u%04x' "$code"; fi
         output+="$char" ;;
    esac
  done
  printf '%s"' "$output"
}
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
transfer_status=0
http_status="$(curl \
  --silent --show-error --max-time 30 --request POST \
  --header "Authorization: Bearer $CRYPTANIO_API_KEY" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data-binary '{"project":'"$(json_string "$CRYPTANIO_PROJECT_ID")"',"chain":"ethereum","address":"0x52908400098527886E0F7030069857D2E4169EE7","asset":"native","label":"Treasury"}' \
  "https://api.cryptanio.com/v1/watches" \
  --output "$response_file" --write-out '%{http_code}')" || transfer_status=$?
if [[ "$http_status" == 2?? ]]; then
  cat "$response_file"
  exit "$transfer_status"
fi
printf 'HTTP %s\n' "$http_status" >&2
cat "$response_file" >&2
exit 1
Descargar ejemplo
Go
// Go; standard library only. Run: go run request.go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
    "time"
)

func env(name string) string {
    value := os.Getenv(name)
    if value == "" { fmt.Fprintln(os.Stderr, "Set", name); os.Exit(1) }
    return value
}
func run() error {
    path := "/v1/watches"

    endpoint, err := url.Parse("https://api.cryptanio.com" + path)
    if err != nil { return err }
    query := endpoint.Query()

    endpoint.RawQuery = query.Encode()
    var payload map[string]any
    if err := json.Unmarshal([]byte("{\"project\":\"1002\",\"chain\":\"ethereum\",\"address\":\"0x52908400098527886E0F7030069857D2E4169EE7\",\"asset\":\"native\",\"label\":\"Treasury\"}"), &payload); err != nil { return err }
    payload["project"] = env("CRYPTANIO_PROJECT_ID")
    body, err := json.Marshal(payload)
    if err != nil { return err }
    request, err := http.NewRequest("POST", endpoint.String(), bytes.NewReader(body))
    if err != nil { return err }
    request.Header.Set("Authorization", "Bearer " + env("CRYPTANIO_API_KEY"))
    request.Header.Set("Accept", "application/json")
    request.Header.Set("Content-Type", "application/json")
    client := &http.Client{Timeout: 30 * time.Second, CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
    response, err := client.Do(request)
    if err != nil { return err }
    defer response.Body.Close()
    if response.StatusCode < 200 || response.StatusCode >= 300 {
        body, err := io.ReadAll(response.Body)
        if err != nil { return err }
        return fmt.Errorf("HTTP %d: %s", response.StatusCode, body)
    }
    _, err = io.Copy(os.Stdout, response.Body)
    return err
}
func main() {
    if err := run(); err != nil { fmt.Fprintln(os.Stderr, err); os.Exit(1) }
}
Descargar ejemplo
Rust
// Cargo.toml dependencies:
// reqwest = { version = "=0.12.24", features = ["blocking", "json"] }
// serde_json = "=1.0.145"
use std::{error::Error, io, time::Duration};
use reqwest::{blocking::Client, redirect::Policy, Method, Url};

fn env(name: &str) -> Result<String, Box<dyn Error>> {
    let value = std::env::var(name)?;
    if value.is_empty() { return Err(format!("Set {name}").into()); }
    Ok(value)
}
fn run() -> Result<(), Box<dyn Error>> {
    let mut url = Url::parse("https://api.cryptanio.com")?;
    {
        let mut segments = url.path_segments_mut().map_err(|_| "Invalid base URL")?;
        segments.clear();
        segments.push("v1");
        segments.push("watches");
    }
    let client = Client::builder().timeout(Duration::from_secs(30)).redirect(Policy::none()).build()?;
    let request = client.request(Method::POST, url)
        .header("Authorization", format!("Bearer {}", env("CRYPTANIO_API_KEY")?))
        .header("Accept", "application/json".to_owned())
        .header("Content-Type", "application/json".to_owned());
    let mut body: serde_json::Value = serde_json::from_str("{\"project\":\"1002\",\"chain\":\"ethereum\",\"address\":\"0x52908400098527886E0F7030069857D2E4169EE7\",\"asset\":\"native\",\"label\":\"Treasury\"}")?;
    body["project"] = serde_json::Value::String(env("CRYPTANIO_PROJECT_ID")?);
    let request = request.json(&body);
    let mut response = request.send()?;
    let status = response.status();
    if !status.is_success() { return Err(format!("HTTP {}: {}", status.as_u16(), response.text()?).into()); }
    io::copy(&mut response, &mut io::stdout())?;
    Ok(())
}
fn main() {
    if let Err(error) = run() { eprintln!("{error}"); std::process::exit(1); }
}
Descargar ejemplo
PHP
<?php
// PHP 8 with the cURL extension. Run this on your server.
function env(string $name): string {
    $value = getenv($name);
    if ($value === false || $value === '') throw new RuntimeException('Set ' . $name);
    return $value;
}
try {
    $path = '/v1/watches';

    $query = [

    ];
    $url = 'https://api.cryptanio.com' . $path . ($query ? '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986) : '');
    $headers = [
        'Authorization: ' . 'Bearer ' . env('CRYPTANIO_API_KEY'),
        'Accept: ' . 'application/json',
        'Content-Type: ' . 'application/json',
    ];
    $body = json_decode('{"project":"1002","chain":"ethereum","address":"0x52908400098527886E0F7030069857D2E4169EE7","asset":"native","label":"Treasury"}', true, 512, JSON_THROW_ON_ERROR);
    $body['project'] = env('CRYPTANIO_PROJECT_ID');
    $curl = curl_init($url);
    curl_setopt_array($curl, [
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => false,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_POSTFIELDS => json_encode($body, JSON_THROW_ON_ERROR),
    ]);
    $response = curl_exec($curl);
    if ($response === false) throw new RuntimeException(curl_error($curl));
    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    if ($status < 200 || $status >= 300) throw new RuntimeException('HTTP ' . $status . ': ' . $response);
    echo $response;
} catch (Throwable $error) {
    fwrite(STDERR, $error->getMessage() . PHP_EOL);
    exit(1);
}
Descargar ejemplo
Python
# Python 3; standard library only.
import json
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import quote, urlencode
from urllib.request import HTTPRedirectHandler, Request, build_opener

def env(name):
    result = os.environ.get(name)
    if not result:
        raise ValueError("Set " + name)
    return result

class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

try:
    path = "/v1/watches"

    query = {

    }
    url = "https://api.cryptanio.com" + path + ("?" + urlencode(query) if query else "")
    headers = {
        "Authorization": "Bearer " + env("CRYPTANIO_API_KEY"),
        "Accept": "application/json",
        "Content-Type": "application/json",
    }
    body = json.loads("{\"project\":\"1002\",\"chain\":\"ethereum\",\"address\":\"0x52908400098527886E0F7030069857D2E4169EE7\",\"asset\":\"native\",\"label\":\"Treasury\"}")
    body["project"] = env("CRYPTANIO_PROJECT_ID")
    data = json.dumps(body).encode("utf-8")
    request = Request(url, data=data, headers=headers, method="POST")
    with build_opener(NoRedirect()).open(request, timeout=30) as response:
        if not 200 <= response.status < 300:
            raise ValueError("HTTP " + str(response.status))
        sys.stdout.buffer.write(response.read())
except HTTPError as error:
    print("HTTP " + str(error.code) + ": " + error.read().decode("utf-8", errors="replace"), file=sys.stderr)
    sys.exit(1)
except (ValueError, URLError, OSError) as error:
    print(str(error), file=sys.stderr)
    sys.exit(1)
Descargar ejemplo
Node.js
// Node.js 18+. Run on your server, never in a browser.
const env = name => {
  const result = process.env[name];
  if (!result) throw new Error(`Set ${name}`);
  return result;
};
try {
  let path = "/v1/watches";

  const url = new URL(path, "https://api.cryptanio.com");

  const headers = {
    "Authorization": "Bearer " + env("CRYPTANIO_API_KEY"),
    "Accept": "application/json",
    "Content-Type": "application/json",
  };
  const body = {
    "project": "1002",
    "chain": "ethereum",
    "address": "0x52908400098527886E0F7030069857D2E4169EE7",
    "asset": "native",
    "label": "Treasury"
  };
  body["project"] = env("CRYPTANIO_PROJECT_ID");
  const response = await fetch(url, {
    method: "POST", headers, redirect: "manual",
    signal: AbortSignal.timeout(30_000), body: JSON.stringify(body),
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
  if (response.body) {
    for await (const chunk of response.body) process.stdout.write(chunk);
  }
} catch (error) {
  console.error(error.message);
  process.exitCode = 1;
}
Descargar ejemplo

Respuestas y errores

201 Respuesta correcta.
CampoTipoObligatorioDescripción
idstringSíIdentificador opaco; consérvalo como cadena.
minLength: 1
project_idstringSíIdentificador opaco; consérvalo como cadena.
minLength: 1
servicestringSíServicio del proyecto.
monitoring
book_address_idstringSíID de la dirección coincidente en la libreta de direcciones.
minLength: 1
statusstringSíEstado de vinculación proyecto-dirección.
active, paused, deleted
chainstringSíCódigo de red.
addressstringSíDirección normalizada.
assetstringSíActivos en la cadena de respuesta; varios activos se separan por comas.
metaobjectNoEtiqueta y nota de la dirección, si están configuradas.
watched_asstringNoIdentificador adicional de la dirección, cuando lo utiliza la red.
sandboxbooleanNotrue para una vigilancia de prueba; la omisión significa false.
watch_outgoingbooleanSíIndica si se vigilan operaciones salientes.
origin_kindsstring[]SíFormas en que se añadió la dirección al proyecto.
created_atstringSíFecha y hora UTC en RFC 3339.
date-time
201 application/json
{
  "id": "1008",
  "project_id": "1002",
  "service": "monitoring",
  "book_address_id": "1007",
  "status": "active",
  "chain": "ethereum",
  "address": "0x52908400098527886E0F7030069857D2E4169EE7",
  "asset": "native",
  "sandbox": true,
  "watch_outgoing": false,
  "origin_kinds": [
    "manual"
  ],
  "created_at": "2026-10-06T10:00:00Z"
}
400 Solicitud inválida (bad_request, unsupported_asset).
CampoTipoObligatorioDescripción
errorobjectSí
400 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
401 No hay una clave API activa válida (unauthorized).
CampoTipoObligatorioDescripción
errorobjectSí
401 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
402 Límite de recursos alcanzado (limit_reached).
CampoTipoObligatorioDescripción
errorobjectSí
402 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
403 La clave no permite la operación, el proyecto, el servicio o la IP; correo sin confirmar.
CampoTipoObligatorioDescripción
errorobjectSí
403 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
409 Conflicto de estado, parámetros de reintento distintos o límite de recursos de pago (conflict, limit_reached, service_inactive).
CampoTipoObligatorioDescripción
errorobjectSí
409 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
429 Demasiadas solicitudes (rate_limited); reintenta después de Retry-After.
CampoTipoObligatorioDescripción
errorobjectSí
429 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
500 Error interno (internal).
CampoTipoObligatorioDescripción
errorobjectSí
500 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
503 Indisponibilidad temporal (unavailable); reintenta con espera progresiva.
CampoTipoObligatorioDescripción
errorobjectSí
503 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}

Gestión de errores y reintentos seguros

Objetos anidados

Watch

CampoTipoObligatorioDescripción
idstringSíIdentificador opaco; consérvalo como cadena.
minLength: 1
project_idstringSíIdentificador opaco; consérvalo como cadena.
minLength: 1
servicestringSíServicio del proyecto.
monitoring
book_address_idstringSíID de la dirección coincidente en la libreta de direcciones.
minLength: 1
statusstringSíEstado de vinculación proyecto-dirección.
active, paused, deleted
chainstringSíCódigo de red.
addressstringSíDirección normalizada.
assetstringSíActivos en la cadena de respuesta; varios activos se separan por comas.
metaobjectNoEtiqueta y nota de la dirección, si están configuradas.
watched_asstringNoIdentificador adicional de la dirección, cuando lo utiliza la red.
sandboxbooleanNotrue para una vigilancia de prueba; la omisión significa false.
watch_outgoingbooleanSíIndica si se vigilan operaciones salientes.
origin_kindsstring[]SíFormas en que se añadió la dirección al proyecto.
created_atstringSíFecha y hora UTC en RFC 3339.
date-time
ID

Identificador opaco. Su formato no está garantizado; no lo conviertas a número.

string Identificador opaco. Su formato no está garantizado; no lo conviertas a número.

StringMap

object

WatchRequest

CampoTipoObligatorioDescripción
projectstringNoID del proyecto. Obligatorio para listar o crear vigilancias salvo que la clave esté limitada a un proyecto. Para las demás operaciones, la omisión usa el contexto de cuenta/proyecto de la operación; indícalo explícitamente.
chainstringSíCódigo de red de GET /v1/chains.
minLength: 1
addressstringSíDirección en la red seleccionada; validada y normalizada.
minLength: 1
assetstringNoActivo predeterminado para exact: native, símbolo compatible o identificador del token.
Predeterminado: native
labelstringNoEtiqueta de la libreta de direcciones.
maxLength: 60
notestringNoNota opcional de la libreta de direcciones.
maxLength: 280
watch_outgoingbooleanNoRecibir también operaciones salientes; la red debe admitirlas.
Predeterminado: false
asset_policystringNoexact selecciona un activo; allow usa asset_ids; all selecciona todos los activos de la red. Las redes sin tokens solo admiten native/exact.
exact, allow, all; Predeterminado: exact
asset_idsstring[]NoExactamente uno para exact, al menos uno para allow y vacío para all. Con exact y una lista vacía se usa asset.
maxItems: 100
excluded_asset_idsstring[]NoActivos que se excluirán.
maxItems: 100
min_confirmationsintegerNoConfirmaciones mínimas.
Predeterminado: 0; minimum: 0
min_amountstringNoUmbral no negativo en unidades mínimas, no un importe decimal.
pattern: ^[0-9]+$
watch_contractsbooleanNoRecibir eventos de contrato compatibles.
Predeterminado: false
watch_unexpected_assetsbooleanNoRecibir eventos de activos inesperados.
Predeterminado: false
RawAmount

string

Error

CampoTipoObligatorioDescripción
errorobjectSí