Source: https://cryptanio.com/es/docs/reference/create-watch/
Contract / release / updated: v1 / 1.0.0 62 / 2026-10-10

[Referencia de la API](https://cryptanio.com/es/docs.html#reference)

# Crear una vigilancia de Monitoring

POST `/v1/watches`

Contrato v1 / 1.0.0 62 / 2026-10-10

[Markdown](https://cryptanio.com/es/docs/reference/create-watch/index.md) [OpenAPI](https://cryptanio.com/openapi.json)

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

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `project` | `string` | No | ID 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. |
| `chain` | `string` | Sí | Código de red de GET /v1/chains.; minLength: `1` |
| `address` | `string` | Sí | Dirección en la red seleccionada; validada y normalizada.; minLength: `1` |
| `asset` | `string` | No | Activo predeterminado para exact: native, símbolo compatible o identificador del token.; Predeterminado: `native` |
| `label` | `string` | No | Etiqueta de la libreta de direcciones.; maxLength: `60` |
| `note` | `string` | No | Nota opcional de la libreta de direcciones.; maxLength: `280` |
| `watch_outgoing` | `boolean` | No | Recibir también operaciones salientes; la red debe admitirlas.; Predeterminado: `false` |
| `asset_policy` | `string` | No | exact 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_ids` | `string[]` | No | Exactamente 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_ids` | `string[]` | No | Activos que se excluirán.; maxItems: `100` |
| `min_confirmations` | `integer` | No | Confirmaciones mínimas.; Predeterminado: `0`; minimum: `0` |
| `min_amount` | `string` | No | Umbral no negativo en unidades mínimas, no un importe decimal.; pattern: `^[0-9]+$` |
| `watch_contracts` | `boolean` | No | Recibir eventos de contrato compatibles.; Predeterminado: `false` |
| `watch_unexpected_assets` | `boolean` | No | Recibir eventos de activos inesperados.; Predeterminado: `false` |



### application/json

```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

```bash
#!/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](https://cryptanio.com/files/examples/api/create-watch.sh)



### Go

```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](https://cryptanio.com/files/examples/api/create-watch.go)



### Rust

```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](https://cryptanio.com/files/examples/api/create-watch.rs)



### PHP

```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](https://cryptanio.com/files/examples/api/create-watch.php)



### Python

```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](https://cryptanio.com/files/examples/api/create-watch.py)



### Node.js

```javascript
// 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](https://cryptanio.com/files/examples/api/create-watch.mjs)

## Respuestas y errores

### 201 Respuesta correcta.

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | Sí | Identificador opaco; consérvalo como cadena.; minLength: `1` |
| `project_id` | `string` | Sí | Identificador opaco; consérvalo como cadena.; minLength: `1` |
| `service` | `string` | Sí | Servicio del proyecto.; `monitoring` |
| `book_address_id` | `string` | Sí | ID de la dirección coincidente en la libreta de direcciones.; minLength: `1` |
| `status` | `string` | Sí | Estado de vinculación proyecto-dirección.; `active`, `paused`, `deleted` |
| `chain` | `string` | Sí | Código de red. |
| `address` | `string` | Sí | Dirección normalizada. |
| `asset` | `string` | Sí | Activos en la cadena de respuesta; varios activos se separan por comas. |
| `meta` | `object` | No | Etiqueta y nota de la dirección, si están configuradas. |
| `watched_as` | `string` | No | Identificador adicional de la dirección, cuando lo utiliza la red. |
| `sandbox` | `boolean` | No | true para una vigilancia de prueba; la omisión significa false. |
| `watch_outgoing` | `boolean` | Sí | Indica si se vigilan operaciones salientes. |
| `origin_kinds` | `string[]` | Sí | Formas en que se añadió la dirección al proyecto. |
| `created_at` | `string` | Sí | Fecha y hora UTC en RFC 3339.; `date-time` |



### 201 application/json

```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).

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 400 application/json

```json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
```



### 401 No hay una clave API activa válida (unauthorized).

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 401 application/json

```json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
```



### 402 Límite de recursos alcanzado (limit_reached).

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 402 application/json

```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.

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 403 application/json

```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).

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 409 application/json

```json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
```



### 429 Demasiadas solicitudes (rate_limited); reintenta después de Retry-After.

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 429 application/json

```json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
```



### 500 Error interno (internal).

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 500 application/json

```json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
```



### 503 Indisponibilidad temporal (unavailable); reintenta con espera progresiva.

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |



### 503 application/json

```json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
```



[Gestión de errores y reintentos seguros](https://cryptanio.com/es/docs.html#errors)

## Objetos anidados

### `Watch`

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | Sí | Identificador opaco; consérvalo como cadena.; minLength: `1` |
| `project_id` | `string` | Sí | Identificador opaco; consérvalo como cadena.; minLength: `1` |
| `service` | `string` | Sí | Servicio del proyecto.; `monitoring` |
| `book_address_id` | `string` | Sí | ID de la dirección coincidente en la libreta de direcciones.; minLength: `1` |
| `status` | `string` | Sí | Estado de vinculación proyecto-dirección.; `active`, `paused`, `deleted` |
| `chain` | `string` | Sí | Código de red. |
| `address` | `string` | Sí | Dirección normalizada. |
| `asset` | `string` | Sí | Activos en la cadena de respuesta; varios activos se separan por comas. |
| `meta` | `object` | No | Etiqueta y nota de la dirección, si están configuradas. |
| `watched_as` | `string` | No | Identificador adicional de la dirección, cuando lo utiliza la red. |
| `sandbox` | `boolean` | No | true para una vigilancia de prueba; la omisión significa false. |
| `watch_outgoing` | `boolean` | Sí | Indica si se vigilan operaciones salientes. |
| `origin_kinds` | `string[]` | Sí | Formas en que se añadió la dirección al proyecto. |
| `created_at` | `string` | Sí | 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`

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `project` | `string` | No | ID 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. |
| `chain` | `string` | Sí | Código de red de GET /v1/chains.; minLength: `1` |
| `address` | `string` | Sí | Dirección en la red seleccionada; validada y normalizada.; minLength: `1` |
| `asset` | `string` | No | Activo predeterminado para exact: native, símbolo compatible o identificador del token.; Predeterminado: `native` |
| `label` | `string` | No | Etiqueta de la libreta de direcciones.; maxLength: `60` |
| `note` | `string` | No | Nota opcional de la libreta de direcciones.; maxLength: `280` |
| `watch_outgoing` | `boolean` | No | Recibir también operaciones salientes; la red debe admitirlas.; Predeterminado: `false` |
| `asset_policy` | `string` | No | exact 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_ids` | `string[]` | No | Exactamente 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_ids` | `string[]` | No | Activos que se excluirán.; maxItems: `100` |
| `min_confirmations` | `integer` | No | Confirmaciones mínimas.; Predeterminado: `0`; minimum: `0` |
| `min_amount` | `string` | No | Umbral no negativo en unidades mínimas, no un importe decimal.; pattern: `^[0-9]+$` |
| `watch_contracts` | `boolean` | No | Recibir eventos de contrato compatibles.; Predeterminado: `false` |
| `watch_unexpected_assets` | `boolean` | No | Recibir eventos de activos inesperados.; Predeterminado: `false` |

### `RawAmount`

`string`

### `Error`

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `error` | `object` | Sí |  |
