Sygnet

Sygnet — Automatización para creadores Sygnet — Automation for creators

Certifica y publica el badge sin pasos manuales Certify and publish the badge without manual steps

¿Para quién es esto? Para creadores con un pipeline de publicación — un script que procesa vídeos, un CMS con hooks, un bot que programa posts — y quieren que la certificación SIA y el badge aparezcan solos, sin abrir el navegador. Si publicas de forma manual desde la web, no necesitas esto. Who is this for? For creators with a publishing pipeline — a script that processes videos, a CMS with hooks, a bot that schedules posts — who want SIA certification and the badge to happen automatically, without opening the browser. If you publish manually from the web, you don't need this.

1. El flujo completo en tres pasos 1. The complete flow in three steps

El navegador no interviene en ningún momento. Todo ocurre en tu script o pipeline: The browser is never involved. Everything happens in your script or pipeline:

1

Hash

SHA3-512 del archivo, calculado en tu máquina. El archivo nunca sale. SHA3-512 of the file, computed on your machine. The file never leaves.

2

CertificarCertify

POST al API con el hash y tu API key. Sygnet devuelve confirmación. POST to the API with the hash and your API key. Sygnet returns confirmation.

3

Badge

La URL del widget es determinista. La construyes tú, sin llamada extra. The widget URL is deterministic. You build it yourself, no extra call needed.

# Flow summary / Resumen del flujo
hash = sha3_512(my_file.pdf)
cert = sygnet_api.post(hash, sia=1, label="My video")
widget = f"https://mysygnet.com/pages/widget.html?hash={hash}"
# → embed widget on your site / embed en tu web

2. Calcular el hash fuera del navegador 2. Computing the hash outside the browser

Sygnet usa SHA3-512: 128 caracteres hexadecimales, algoritmo estándar NIST. A diferencia del SHA2 más común, SHA3 tiene una construcción diferente (Keccak) que lo hace resistente a ataques de extensión de longitud. Esto es importante: el mismo archivo siempre produce el mismo hash, así que puedes verificar más tarde sin guardar el archivo. Sygnet uses SHA3-512: 128 hexadecimal characters, NIST standard algorithm. Unlike the more common SHA2, SHA3 has a different construction (Keccak) that makes it resistant to length-extension attacks. Key point: the same file always produces the same hash, so you can verify later without keeping the file.

Python 3.6+

import hashlib

def hash_file(path: str) -> str:
    """SHA3-512 of a file, memory-efficient (64 KB chunks)."""
    h = hashlib.sha3_512()
    with open(path, 'rb') as f:
        for chunk in iter(lambda: f.read(65536), b''):
            h.update(chunk)
    return h.hexdigest()

# Usage
print(hash_file("my-article.pdf"))
# → "a1b2c3d4e5f6..."  (128 chars)

No necesita dependencias externas. hashlib es librería estándar de Python. No external dependencies. hashlib is Python's standard library.

Node.js

// Option A — js-sha3 (compatible with all Node versions)
// npm install js-sha3
const { sha3_512 } = require('js-sha3');
const fs           = require('fs');

function hashFile(path) {
    return sha3_512(fs.readFileSync(path));
}

// Option B — native crypto (Node 21+ / OpenSSL 3+)
const crypto = require('crypto');
const fs     = require('fs');

function hashFile(path) {
    return crypto.createHash('sha3-512')
        .update(fs.readFileSync(path))
        .digest('hex');
}

Usa la opción A si necesitas compatibilidad amplia. La opción B no requiere dependencias pero solo funciona en Node.js 21+. Use option A for broad compatibility. Option B requires no dependencies but only works on Node.js 21+.

Línea de comandosCommand line

# Python — works on any system with Python 3.6+
python3 -c "
import hashlib, sys
h = hashlib.sha3_512()
[h.update(c) for c in iter(lambda: open(sys.argv[1],'rb').read(65536), b'')]
print(h.hexdigest())
" my-file.pdf

# OpenSSL 3+ (Linux / macOS Ventura+)
openssl dgst -sha3-512 my-file.pdf | awk '{print $2}'
El archivo nunca sale de tu máquina. Solo el hash (128 caracteres) se envía a Sygnet. No es posible reconstruir el archivo a partir del hash — es matemáticamente unidireccional. The file never leaves your machine. Only the hash (128 characters) is sent to Sygnet. It is impossible to reconstruct the file from the hash — it is mathematically one-way.

3. Emitir el certificado vía API 3. Issuing the certificate via API

Primero necesitas una API key: Dashboard → Claves API → + Nueva clave. Guarda la clave al generarla (no se puede recuperar después). First you need an API key: Dashboard → API Keys → + New key. Save the key when you generate it (it cannot be recovered later).

POST /api/certificados

Cabecera requeridaRequired header

Authorization: Bearer apikey_your_key_here

Body JSON

{
  "hash":          "a1b2c3d4...",                // SHA3-512, 128 chars — required
  "algorithm":     "SHA3-512",                   // exact string, case-sensitive — SHA3-512 (default) | SHA256
  "sia_level":     1,                            // 1–5, required
  "description":   "My video: AI in 2026",       // visible label, optional
  "published_url": "https://youtube.com/watch?v=..." // publication URL, optional
}

RespuestaResponse

// Success — always HTTP 200, whether newly created or already existing
{ "ok": true, "hash": "a1b2c3d4...", "new": true }
// If a certificate with this hash was already active:
{ "ok": true, "hash": "a1b2c3d4...", "new": false, "own": true }

// Error (400/401/404/429)
{ "ok": false, "error": "Hash inválido (se esperaba SHA3-512 hex de 128 chars)", "error_code": "invalid_hash_format" }

Python — requests

import requests

def certificar(hash_: str, titulo: str, sia: int = 1, published_url: str = None) -> dict:
    payload = {
        "hash":        hash_,
        "algorithm":   "SHA3-512",
        "sia_level":   sia,
        "description": titulo,
    }
    if published_url:
        payload["published_url"] = published_url

    r = requests.post(
        "https://mysygnet.com/api/certificados",
        headers={"Authorization": "Bearer apikey_YOUR_KEY"},
        json=payload,
        timeout=15
    )
    r.raise_for_status()
    return r.json()

Node.js — native fetch

async function certificar(hash, titulo, sia = 1, publishedUrl = null) {
    const payload = { hash, algorithm: 'SHA3-512', sia_level: sia, description: titulo };
    if (publishedUrl) payload.published_url = publishedUrl;

    const r = await fetch('https://mysygnet.com/api/certificados', {
        method:  'POST',
        headers: {
            'Authorization': 'Bearer apikey_YOUR_KEY',
            'Content-Type':  'application/json'
        },
        body: JSON.stringify(payload)
    });
    if (!r.ok) throw new Error(await r.text());
    return r.json();
}

Idempotente: si el mismo hash ya está certificado y activo, Sygnet devuelve ok: true, new: false sin crear un duplicado. Puedes llamar a este endpoint varias veces sin miedo — usa el campo new de la respuesta si necesitas saber si se creó o ya existía. Idempotent: if the same hash is already certified and active, Sygnet returns ok: true, new: false without creating a duplicate. You can call this endpoint multiple times safely — use the response's new field if you need to know whether it was just created.

Rate limit: 20 certificaciones por hora por IP de origen (no por cuenta). Si tu pipeline corre en un servidor con IP fija y necesitas más volumen, contacta a soporte — crear varias cuentas no evita el límite porque se aplica por IP. Rate limit: 20 certifications per hour per source IP (not per account). If your pipeline runs on a fixed-IP server and you need higher volume, contact support — creating multiple accounts won't bypass the limit since it's applied per IP.

4. Construir la URL del widget (determinista) 4. Building the widget URL (deterministic)

Esta es la ventaja clave frente a otros sistemas: no necesitas una llamada extra al API para obtener el badge. Conoces el hash porque tú lo calculaste — con eso ya tienes todas las URLs: This is the key advantage over other systems: you don't need an extra API call to get the badge. You know the hash because you computed it — from that you already have all the URLs:

Todas las URLs, a partir del hash All URLs, from the hash

HASH = "a1b2c3d4..."  # 128 chars you computed

# Badge SVG (embeddable as <img>, updates in real time)
badge_url   = f"https://mysygnet.com/api/certificados/{HASH}/badge"

# Interactive widget (iframe, dark card 300×100px, click → verify)
widget_url  = f"https://mysygnet.com/pages/widget.html?hash={HASH}"

# OBS Browser Source (transparent background, auto-refresh 60s)
overlay_url = f"https://mysygnet.com/pages/overlay.html?hash={HASH}"

# Raw JSON API — for scripts/monitoring, NOT for sharing with humans
api_url     = f"https://mysygnet.com/api/certificados/{HASH}"

# Certificate PDF (downloadable)
pdf_url     = f"https://mysygnet.com/api/certificados/{HASH}/pdf"

# Iframe snippet ready to paste on your site
iframe = (
    f'<iframe src="{widget_url}" width="300" height="100" '
    f'frameborder="0" scrolling="no" '
    f'style="border:none;overflow:hidden;border-radius:12px"></iframe>'
)

La página de verificación para humanos (no el JSON de la API) The human verification page (not the API's JSON)

/api/certificados/{HASH} de arriba devuelve JSON crudo — perfecto para tu script, pero si un desconocido hace clic en él desde YouTube o un badge, solo ve texto técnico. Para compartir con tu audiencia usa mysygnet.com/?cert=..., que muestra una página legible con el nombre del creador, la declaración y un CTA — este es el link que hay que pegar en descripciones, bios y posts. The /api/certificados/{HASH} URL above returns raw JSON — perfect for your script, but if a stranger clicks it from YouTube or a badge, all they see is technical text. To share with your audience use mysygnet.com/?cert=..., which renders a readable page with the creator's name, the declaration, and a CTA — this is the link to paste in descriptions, bios, and posts.

# Python — build the human-readable verification link
import json, base64

def build_share_url(hash_: str, sia_level: int, caduca_at=None, description: str = None) -> str:
    payload = {"h": hash_, "s": sia_level}
    if caduca_at:
        payload["e"] = int(caduca_at.timestamp())  # unix timestamp
    if description:
        payload["l"] = description
    b64 = base64.b64encode(json.dumps(payload, separators=(",", ":")).encode()).decode()
    return f"https://mysygnet.com/?cert={b64}"

# share_url = build_share_url(HASH, sia_level=1, description="My video: AI in 2026")
# → https://mysygnet.com/?cert=eyJoIjoi...

Badge SVG vs. Widget iframe

Badge SVGúsalo donde no admiten iframes: GitHub README, Notion, email HTML. Es una imagen que se actualiza sola. use it where iframes aren't allowed: GitHub README, Notion, HTML email. It's a self-updating image.
Widget iframeúsalo en tu web o blog. Es interactivo: muestra el nivel SIA, el owner y enlaza a la verificación con un clic. use it on your site or blog. It's interactive: shows the SIA level, owner, and links to verification on click.

Parámetro ?lang=?lang= parameter

Añade ?hash=...&lang=en para el widget y overlay en inglés. Por defecto el idioma es español. Úsalo si tu audiencia es internacional. Add ?hash=...&lang=en for the widget and overlay in English. Default language is Spanish. Use this for international audiences.

5. Pipeline completo — ejemplo real 5. Full pipeline — real example

Tienes un script que procesa tus vídeos o artículos antes de publicarlos. Añade estas dos funciones y ya tienes certificación SIA + badge automáticos: You have a script that processes your videos or articles before publishing. Add these two functions and you get automatic SIA certification + badge:

Python — pipeline completo Python — full pipeline

Certifica un archivo y devuelve todas las URLs listas para usar. Certify a file and return all ready-to-use URLs.

import hashlib
import json
import base64
import requests

SYGNET_API_KEY = "apikey_YOUR_KEY"
BASE            = "https://mysygnet.com"


def hash_file(path: str) -> str:
    h = hashlib.sha3_512()
    with open(path, 'rb') as f:
        for chunk in iter(lambda: f.read(65536), b''):
            h.update(chunk)
    return h.hexdigest()


def certificar_y_badge(
    file_path: str,
    titulo: str,
    sia: int = 1,
    published_url: str = None,
    lang: str = "en"
) -> dict:
    """
    Certify a file and return hash + all useful URLs.
    sia: 1=100% human  2=human+AI  3=co-authored  4=mainly AI  5=100% AI
    """
    hash_ = hash_file(file_path)

    payload = {
        "hash":        hash_,
        "algorithm":   "SHA3-512",
        "sia_level":   sia,
        "description": titulo,
    }
    if published_url:
        payload["published_url"] = published_url

    r = requests.post(
        f"{BASE}/api/certificados",
        headers={"Authorization": f"Bearer {SYGNET_API_KEY}"},
        json=payload,
        timeout=15
    )
    r.raise_for_status()

    widget_url  = f"{BASE}/pages/widget.html?hash={hash_}&lang={lang}"
    overlay_url = f"{BASE}/pages/overlay.html?hash={hash_}&lang={lang}"
    iframe      = (
        f'<iframe src="{widget_url}" width="300" height="100" '
        f'frameborder="0" scrolling="no" '
        f'style="border:none;overflow:hidden;border-radius:12px"></iframe>'
    )
    badge_img   = f'<img src="{BASE}/api/certificados/{hash_}/badge" alt="Sygnet SIA certificate">'

    # Human-readable page to share with your audience (YouTube description, bio, post)
    share_payload = {"h": hash_, "s": sia, "l": titulo}
    share_b64     = base64.b64encode(json.dumps(share_payload, separators=(",", ":")).encode()).decode()
    share_url     = f"{BASE}/?cert={share_b64}"

    return {
        "hash":        hash_,
        "widget_url":  widget_url,
        "overlay_url": overlay_url,
        "iframe":      iframe,
        "badge_img":   badge_img,
        "share_url":   share_url,                        # for humans — paste this on YouTube/bio/posts
        "api_url":     f"{BASE}/api/certificados/{hash_}",  # raw JSON — for scripts/monitoring only
        "pdf_url":     f"{BASE}/api/certificados/{hash_}/pdf",
    }


# ── Example usage ─────────────────────────────────────────────────────────────

cert = certificar_y_badge(
    file_path     = "episode-42.mp4",
    titulo        = "Episode 42: The future of AI",
    sia           = 1,                                         # 100% human
    published_url = "https://www.youtube.com/watch?v=XXXX",
    lang          = "en"
)

print(f"Hash: {cert['hash'][:16]}…")
print(f"Share with your audience: {cert['share_url']}")
print()
print("Paste this on your site:")
print(cert['iframe'])
print()
print("For GitHub README (no iframes allowed):")
print(cert['badge_img'])

Node.js — mismo pipelinesame pipeline

const { sha3_512 } = require('js-sha3');   // npm install js-sha3
const fs            = require('fs');

const SYGNET_API_KEY = 'apikey_YOUR_KEY';
const BASE           = 'https://mysygnet.com';

async function certificarYBadge(filePath, titulo, sia = 1, publishedUrl = null, lang = 'en') {
    const hash = sha3_512(fs.readFileSync(filePath));

    const payload = { hash, algorithm: 'SHA3-512', sia_level: sia, description: titulo };
    if (publishedUrl) payload.published_url = publishedUrl;

    const r = await fetch(`${BASE}/api/certificados`, {
        method:  'POST',
        headers: { 'Authorization': `Bearer ${SYGNET_API_KEY}`, 'Content-Type': 'application/json' },
        body:    JSON.stringify(payload)
    });
    if (!r.ok) throw new Error(await r.text());

    const widgetUrl  = `${BASE}/pages/widget.html?hash=${hash}&lang=${lang}`;
    const overlayUrl = `${BASE}/pages/overlay.html?hash=${hash}&lang=${lang}`;
    const iframe     = `<iframe src="${widgetUrl}" width="300" height="100" frameborder="0" scrolling="no" style="border:none;overflow:hidden;border-radius:12px"></iframe>`;

    // Human-readable page to share with your audience (YouTube description, bio, post)
    const sharePayload = { h: hash, s: sia, l: titulo };
    const shareB64      = Buffer.from(JSON.stringify(sharePayload)).toString('base64');
    const shareUrl       = `${BASE}/?cert=${shareB64}`;

    return { hash, widgetUrl, overlayUrl, iframe,
             shareUrl,                                    // for humans — paste this on YouTube/bio/posts
             apiUrl: `${BASE}/api/certificados/${hash}`,   // raw JSON — for scripts/monitoring only
             pdfUrl: `${BASE}/api/certificados/${hash}/pdf` };
}

// Usage
certificarYBadge('episode-42.mp4', 'Episode 42: AI', 1, 'https://youtu.be/XXXX')
    .then(cert => {
        console.log('Share with your audience:', cert.shareUrl);
        console.log('Iframe:\n', cert.iframe);
    });

6. Sin código: Make · n8n · Zapier 6. No-code: Make · n8n · Zapier

Si tu pipeline usa una herramienta de automatización visual, el flujo es el mismo — solo que con nodos en lugar de líneas de código. If your pipeline uses a visual automation tool, the flow is the same — just with nodes instead of lines of code.

Limitación importante: estas plataformas no calculan SHA3-512 de archivos de forma nativa. Necesitas un paso previo que compute el hash: una Cloud Function, un script local, o un nodo HTTP hacia un servicio de hashing. Una vez tienes el hash, el resto del flujo es sencillo. Important limitation: these platforms don't natively compute SHA3-512 for files. You need a prior step that computes the hash: a Cloud Function, a local script, or an HTTP node calling a hashing service. Once you have the hash, the rest of the flow is straightforward.

Flujo en Make / n8n / Zapier Flow in Make / n8n / Zapier

  1. 1

    Trigger: tu evento de publicación Trigger: your publish event

    Nuevo archivo en Google Drive, nuevo post en Ghost, nuevo episodio en RSS, etc. New file in Google Drive, new post in Ghost, new episode in RSS, etc.

  2. 2

    HTTP Request → tu endpoint de hashing HTTP Request → your hashing endpoint

    Un script o Cloud Function que recibe el archivo (o su URL) y devuelve el SHA3-512. Puedes usar la función Python del paso 2 desplegada en Railway, Render o Google Cloud Functions. A script or Cloud Function that receives the file (or its URL) and returns the SHA3-512. You can deploy the Python function from step 2 on Railway, Render, or Google Cloud Functions.

  3. 3

    HTTP Request → POST https://mysygnet.com/api/certificados

    Cabecera: Authorization: Bearer apikey_YOUR_KEY · Body JSON con hash, algorithm, sia_level, description. Header: Authorization: Bearer apikey_YOUR_KEY · JSON body with hash, algorithm, sia_level, description.

  4. 4

    Set variable: construir la URL del widget Set variable: build the widget URL

    En Make: usa el módulo "Set variable" con el valor https://mysygnet.com/pages/widget.html?hash={{hash}} donde hash es la variable del paso anterior. In Make: use the "Set variable" module with value https://mysygnet.com/pages/widget.html?hash={{hash}} where hash is the variable from the previous step.

  5. 5

    Actualizar tu CMS / plataforma con el widget Update your CMS / platform with the widget

    HTTP Request a la API de Ghost, WordPress, Webflow, etc., con el snippet iframe ya construido. HTTP Request to the Ghost, WordPress, Webflow API, etc., with the already-built iframe snippet.

7. Flujo event-driven con webhooks 7. Event-driven flow with webhooks

El pipeline anterior es síncrono: tu script espera la respuesta del POST para continuar. Si tu arquitectura es asíncrona (cola de mensajes, worker), el webhook es más natural: certificas, Sygnet te avisa cuando está listo, tu worker incrusta el badge. The previous pipeline is synchronous: your script waits for the POST response to continue. If your architecture is asynchronous (message queue, worker), the webhook is more natural: you certify, Sygnet notifies you when it's ready, your worker embeds the badge.

Pipeline síncrono (POST → esperar respuesta) Synchronous pipeline (POST → wait for response)

Mejor para: scripts simples, pipelines lineales, Make/Zapier. Best for: simple scripts, linear pipelines, Make/Zapier.

El hash lo construyes tú → la URL del widget es inmediata. You build the hash → the widget URL is immediate.

Flujo event-driven (webhook) Event-driven flow (webhook)

Mejor para: workers asíncronos, sistemas de cola, arquitecturas desacopladas. Best for: async workers, queue systems, decoupled architectures.

El webhook dispara tu worker con el hash — mismo resultado. The webhook triggers your worker with the hash — same result.

Ejemplo: worker que recibe el webhook y actualiza el CMS Example: worker that receives the webhook and updates the CMS

Flask. Para más detalle sobre la verificación HMAC, ver laFor more on HMAC verification, see the Guía de webhooksWebhooks Guide .

import hmac, hashlib, json
from flask import Flask, request, abort

app    = Flask(__name__)
SECRET = "your_webhook_secret"
BASE   = "https://mysygnet.com"

@app.route("/sygnet-webhook", methods=["POST"])
def recibir():
    body  = request.get_data()
    firma = request.headers.get("X-Sygnet-Signature", "")
    esp   = "sha256=" + hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(esp, firma):
        abort(401)

    evento = json.loads(body)
    hash_  = evento["hash"]

    # Widget URL is deterministic — no extra API call needed
    widget_url  = f"{BASE}/pages/widget.html?hash={hash_}"
    overlay_url = f"{BASE}/pages/overlay.html?hash={hash_}"
    iframe      = (
        f'<iframe src="{widget_url}" width="300" height="100" '
        f'frameborder="0" scrolling="no" '
        f'style="border:none;overflow:hidden;border-radius:12px"></iframe>'
    )

    # Update your CMS / database with the iframe
    actualizar_cms(evento["description"], iframe)

    return "", 200

def actualizar_cms(titulo, iframe_html):
    # Your logic: Ghost API, WordPress API, Webflow CMS, etc.
    print(f"Updating '{titulo}' with badge:\n{iframe_html}")

if __name__ == "__main__":
    app.run(port=5000)

8. Incrustar el widget según la plataforma 8. Embedding the widget by platform

Cada plataforma tiene sus propias restricciones con los iframes: Each platform has its own iframe restrictions:

YouTube

Las descripciones no admiten HTML. Pega el link para humanos (mysygnet.com/?cert=..., ver sección 4) — no el endpoint /api/certificados/HASH, que devuelve JSON crudo, no una página legible. Los usuarios hacen clic y ven una página con el nombre del creador y la declaración. Descriptions don't support HTML. Paste the human-facing link (mysygnet.com/?cert=..., see section 4) — not the /api/certificados/HASH endpoint, which returns raw JSON, not a readable page. Users click it and see a page with the creator's name and declaration.

Gh

GitHub README

GitHub no permite iframes en Markdown. Usa el badge SVG enlazado: GitHub doesn't allow iframes in Markdown. Use the linked SVG badge: [![Sygnet](https://mysygnet.com/api/certificados/HASH/badge)](https://mysygnet.com/api/certificados/HASH)

👻

Ghost

Inserta un bloque HTML y pega el snippet <iframe>. Funciona en todos los temas. Insert an HTML block and paste the <iframe> snippet. Works in all themes.

W

WordPress

En el editor Gutenberg, añade un bloque "HTML personalizado" y pega el <iframe>. En el editor clásico, cambia a vista HTML y pégalo donde quieras. In the Gutenberg editor, add a "Custom HTML" block and paste the <iframe>. In the classic editor, switch to HTML view and paste it where you want.

📧

Newsletter / EmailNewsletter / Email

La mayoría de clientes de email bloquean iframes. Usa el badge SVG como <img> enlazado al link para humanos (mysygnet.com/?cert=...), o simplemente esa URL en texto plano. Most email clients block iframes. Use the SVG badge as an <img> linked to the human-facing page (mysygnet.com/?cert=...), or simply that URL as plain text.

🎮

OBS (streaming en vivolive streaming)

Añade un Browser Source con la URL del overlay: https://mysygnet.com/pages/overlay.html?hash=HASH. Tamaño recomendado: 400×72 px. Background transparente activado. Add a Browser Source with the overlay URL: https://mysygnet.com/pages/overlay.html?hash=HASH. Recommended size: 400×72 px. Enable transparent background.

9. Preguntas frecuentes 9. FAQ

¿Tengo que subir el archivo a Sygnet? Do I have to upload the file to Sygnet?

No. Sygnet nunca ve tu archivo. Solo recibes el hash de 128 caracteres. El hash es matemáticamente unidireccional: no es posible reconstruir el archivo a partir de él. Eso significa que puedes certificar contenido privado o confidencial sin exponerlo. No. Sygnet never sees your file. Only the 128-character hash is sent. The hash is mathematically one-way: it is impossible to reconstruct the file from it. This means you can certify private or confidential content without exposing it.

¿Qué pasa si certifico el mismo archivo dos veces? What happens if I certify the same file twice?

El endpoint es idempotente. Si ya existe un certificado activo con el mismo hash, Sygnet devuelve ok: true sin crear un duplicado. Puedes llamarlo múltiples veces sin riesgo — útil si tu pipeline no lleva registro de qué ya está certificado. The endpoint is idempotent. If an active certificate with the same hash already exists, Sygnet returns ok: true without creating a duplicate. You can call it multiple times safely — useful if your pipeline doesn't track what's already been certified.

¿Qué nivel SIA debo usar si mezclo contenido propio con IA? What SIA level should I use if I mix my own content with AI?
SIA 1
100% humano — sin asistencia de IA en ningún momento del proceso. 100% human — no AI assistance at any point in the process.
SIA 2
Herramientas IA como corrector ortográfico, resize automático, transcripción. AI tools like spell checker, auto-resize, transcription.
SIA 3
Coautoría: la IA propuso ideas, párrafos o imágenes que tú seleccionaste y editaste. Co-authorship: AI proposed ideas, paragraphs, or images that you selected and edited.
SIA 4
La IA generó la mayor parte; tú supervisaste, editaste y publicaste. AI generated most of it; you supervised, edited, and published.
SIA 5
100% generado por IA sin intervención editorial humana. 100% AI-generated with no human editorial involvement.
¿El widget se actualiza si el certificado expira o es disputado? Does the widget update if the certificate expires or is disputed?

Sí. El widget y el overlay hacen un refresco automático cada 60 segundos. Si el estado del certificado cambia (expira, es revocado o disputado), el color y el texto se actualizan solos en el siguiente ciclo. No tienes que cambiar el snippet — la URL es siempre la misma. Yes. The widget and overlay auto-refresh every 60 seconds. If the certificate status changes (expires, is revoked, or disputed), the colour and text update automatically on the next cycle. You don't need to change the snippet — the URL is always the same.

¿Puedo certificar desde un GitHub Action o CI/CD? Can I certify from a GitHub Action or CI/CD?

Sí — y ya hay una Action reusable que hace todo esto en un solo paso de YAML: fralopgom/Sygnet/.github/actions/sygnet-certify. Guarda tu API key como secret del repositorio y úsala así: Yes — there's already a reusable Action that does all of this in a single step of YAML: fralopgom/Sygnet/.github/actions/sygnet-certify. Store your API key as a repository secret and use it like this:

- name: Certify artifact / Certificar artefacto
  id: sygnet
  uses: fralopgom/Sygnet/.github/actions/sygnet-certify@main
  with:
    file:        dist/app.zip
    sia_level:   1
    description: 'Release ${{ github.ref_name }}'
    api_key:     ${{ secrets.SYGNET_API_KEY }}

- name: Share the verification link / Compartir el link de verificación
  run: echo "${{ steps.sygnet.outputs.share_url }}"

Documentación completa (inputs, outputs, ejemplo con GitHub Releases) en el README de la Action. Si prefieres no depender de una Action de terceros, el equivalente en curl puro es: Full docs (inputs, outputs, GitHub Releases example) in the Action's README. If you'd rather not depend on a third-party Action, the plain-curl equivalent is:

- name: Certify artifact / Certificar artefacto
  run: |
    HASH=$(python3 -c "
    import hashlib, sys
    h = hashlib.sha3_512()
    [h.update(c) for c in iter(lambda: open(sys.argv[1],'rb').read(65536), b'')]
    print(h.hexdigest())
    " dist/app.zip)

    curl -s -X POST https://mysygnet.com/api/certificados \
      -H "Authorization: Bearer ${{ secrets.SYGNET_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d "{\"hash\":\"$HASH\",\"algorithm\":\"SHA3-512\",\"sia_level\":1,\"description\":\"Release v${{ github.ref_name }}\"}"
¿Cómo certifico texto (artículo, guión) en lugar de un archivo binario? How do I certify text (article, script) instead of a binary file?

Hashea el contenido como bytes. En Python: Hash the content as bytes. In Python:

import hashlib

text   = "This is the content of my article..."
hash_  = hashlib.sha3_512(text.encode('utf-8')).hexdigest()
# → Use this hash exactly as you would with a file

Importante: usa siempre la misma codificación (UTF-8) para que el hash sea reproducible. Un espacio extra o un salto de línea diferente produce un hash distinto. Important: always use the same encoding (UTF-8) so the hash is reproducible. An extra space or a different line ending produces a different hash.

← Volver al Dashboard← Back to Dashboard  ·  Referencia APIAPI Docs  ·  Guía de webhooksWebhooks Guide  ·  Sygnet