🔒 Partilhar.Link

API REST — Partilhar.Link

Endpoints para partilha segura e gestão de cofre

Partilha: https://partilhar.link/api/v1/

Cofre: https://partilhar.link/api/v2/

Autenticação: A API v1 é pública (API key opcional). A API v2 requer autenticação (JWT ou API key). Rate limit v1: 30 partilhas por hora por IP.
POST
/api/v1/share/

Cria uma nova partilha segura.

Request Body (JSON)

{
  "share_type":      "url" | "text" | "secret",  // obrigatório
  "content":         "string",                   // obrigatório
  "password":        "string",                   // opcional
  "burn_after_read": false,                       // opcional
  "max_accesses":    null,                        // opcional (int)
  "expires_in":      24,                          // opcional (horas)
  "notify_email":    "email@exemplo.com",         // opcional
  "custom_slug":     "o-meu-slug"                 // opcional
}

Response 201

{
  "slug":          "abc12345",
  "url":           "https://partilhar.link/s/abc12345/",
  "revoke_url":    "https://partilhar.link/revoke/TOKEN32CHARS/",
  "share_type":    "url",
  "is_encrypted":  false,
  "burn_after_read": false,
  "max_accesses":  null,
  "expires_at":    "2024-03-25T12:00:00+00:00",
  "has_password":  false,
  "created_on":    "2024-03-24T10:00:00+00:00"
}

Response 400 (erros)

{
  "errors": {
    "content": "O conteúdo é obrigatório."
  }
}
GET
/api/v1/stats/

Estatísticas gerais da plataforma.

Response 200

{
  "total_shares":    12345,
  "active_shares":   678,
  "total_accesses":  98765
}

Exemplos

cURL — Partilhar URL

curl -X POST https://partilhar.link/api/v1/share/ \
  -H "Content-Type: application/json" \
  -d '{
    "share_type": "url",
    "content": "https://exemplo.com/link-longo",
    "expires_in": 24,
    "burn_after_read": true
  }'

cURL — Partilhar Segredo com Palavra-passe

curl -X POST https://partilhar.link/api/v1/share/ \
  -H "Content-Type: application/json" \
  -d '{
    "share_type": "secret",
    "content": "a-minha-palavra-passe-secreta",
    "password": "chave-de-acesso",
    "burn_after_read": true,
    "notify_email": "eu@exemplo.com"
  }'

Python

import requests

resp = requests.post("https://partilhar.link/api/v1/share/", json={
    "share_type": "text",
    "content": "Conteúdo confidencial",
    "expires_in": 168,  # 7 dias
    "max_accesses": 3,
})
data = resp.json()
print(data["url"])       # link para partilhar
print(data["revoke_url"])  # guardar em privado

JavaScript (fetch)

const res = await fetch('https://partilhar.link/api/v1/share/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    share_type: 'secret',
    content: 'TOKEN_SECRETO_123',
    burn_after_read: true,
    password: 'senha-opcional',
  })
});
const { url, revoke_url } = await res.json();
console.log('Partilha:', url);

Autenticação

POST
/api/v2/auth/login/

Iniciar sessão com email e palavra-passe. Devolve tokens JWT (ou desafio MFA).

Request Body (JSON)

{
  "email": "utilizador@exemplo.com",
  "password": "a-minha-password"
}

Response 200

{
  "access": "eyJ...",
  "refresh": "eyJ...",
  "user": {
    "id": 1,
    "email": "utilizador@exemplo.com"
  }
}

Response 200 (MFA ativo)

{
  "mfa_required": true,
  "mfa_token": "tmp_abc123..."
}
POST
/api/v2/auth/register/

Criar uma nova conta de utilizador.

Request Body (JSON)

{
  "email": "novo@exemplo.com",
  "password": "password-segura-123",
  "password2": "password-segura-123"
}

Response 201

{
  "access": "eyJ...",
  "refresh": "eyJ...",
  "secret_key": "A3-XXXXXX-...",
  "recovery_codes": [
    "ABCD-1234-EFGH",
    "IJKL-5678-MNOP",
    "..."
  ]
}
POST
/api/v2/auth/refresh/

Renovar o token de acesso JWT.

Request Body (JSON)

{
  "refresh": "eyJ..."
}

Response 200

{
  "access": "eyJ..."
}
POST
/api/v2/auth/mfa/verify/

Completar verificação MFA após login.

Request Body (JSON)

{
  "mfa_token": "tmp_abc123...",
  "code": "123456"
}

Response 200

{
  "access": "eyJ...",
  "refresh": "eyJ..."
}

Cofres

GET
/api/v2/vaults/

Listar todos os cofres do utilizador autenticado.

Response 200

[
  {
    "slug": "pessoal",
    "name": "Pessoal",
    "description": "Credenciais pessoais",
    "item_count": 42,
    "created_on": "2026-01-15T10:00:00+00:00"
  }
]
POST
/api/v2/vaults/

Criar um novo cofre.

Request Body (JSON)

{
  "name": "Trabalho",
  "description": "Credenciais de trabalho"
}

Response 201

{
  "slug": "trabalho",
  "name": "Trabalho",
  "description": "Credenciais de trabalho",
  "item_count": 0,
  "created_on": "2026-04-01T12:00:00+00:00"
}
GET
/api/v2/vaults/{slug}/

Detalhes de um cofre específico.

DELETE
/api/v2/vaults/{slug}/

Eliminar um cofre e todos os seus itens.

Response 204

// Sem corpo de resposta

Itens do Cofre

GET
/api/v2/vaults/{slug}/items/

Listar itens de um cofre. Filtros opcionais: ?item_type=login&domain=github.com

Response 200

[
  {
    "id": 1,
    "item_type": "login",
    "title_hint": "GitHub",
    "domain": "github.com",
    "encrypted_data": "base64...",
    "data_iv": "base64...",
    "created_on": "2026-03-20T08:00:00+00:00",
    "updated_on": "2026-03-20T08:00:00+00:00"
  }
]
POST
/api/v2/vaults/{slug}/items/

Adicionar um novo item ao cofre. Os dados são encriptados no cliente.

Request Body (JSON)

{
  "item_type": "login",
  "encrypted_data": "base64...",
  "data_iv": "base64...",
  "domain": "github.com",
  "title_hint": "GitHub"
}

Response 201

{
  "id": 2,
  "item_type": "login",
  "title_hint": "GitHub",
  "domain": "github.com",
  "encrypted_data": "base64...",
  "data_iv": "base64...",
  "created_on": "2026-04-01T12:30:00+00:00",
  "updated_on": "2026-04-01T12:30:00+00:00"
}
GET
/api/v2/vaults/{slug}/items/{id}/

Detalhes de um item específico do cofre.

PUT
/api/v2/vaults/{slug}/items/{id}/

Atualizar um item existente no cofre.

Request Body (JSON)

{
  "encrypted_data": "base64-novo...",
  "data_iv": "base64-novo...",
  "domain": "github.com",
  "title_hint": "GitHub (atualizado)"
}
DELETE
/api/v2/vaults/{slug}/items/{id}/

Eliminar um item do cofre.

GET
/api/v2/vaults/{slug}/items/{id}/history/

Histórico de versões de um item.

Response 200

[
  {
    "version": 2,
    "encrypted_data": "base64...",
    "data_iv": "base64...",
    "changed_on": "2026-04-01T14:00:00+00:00"
  },
  {
    "version": 1,
    "encrypted_data": "base64...",
    "data_iv": "base64...",
    "changed_on": "2026-03-20T08:00:00+00:00"
  }
]

Partilhas (v2)

GET
/api/v2/shares/

Listar todas as partilhas do utilizador autenticado.

POST
/api/v2/shares/

Criar uma nova partilha segura (autenticada).

DELETE
/api/v2/shares/{slug}/

Revogar uma partilha existente.

Saúde de Palavras-passe

GET
/api/v2/health/

Obter o relatório de saúde mais recente das palavras-passe.

Response 200

{
  "total_items": 42,
  "weak_passwords": 3,
  "reused_passwords": 5,
  "breached_passwords": 1,
  "score": 82,
  "generated_on": "2026-04-01T10:00:00+00:00"
}
POST
/api/v2/health/report/

Submeter um novo relatório de saúde calculado no cliente.

Verificação de Fugas

POST
/api/v2/breach/check-password/

Verificar se uma palavra-passe foi comprometida usando k-anonimato (HIBP).

Request Body (JSON)

{
  "sha1_prefix": "5BAA6"
}

Response 200

{
  "results": [
    "1E4C9B93F3F0682250B6CF8331B7EE68FD8:3861493",
    "..."
  ]
}
POST
/api/v2/breach/check-email/

Verificar se um email aparece em fugas de dados conhecidas.

Request Body (JSON)

{
  "email": "utilizador@exemplo.com"
}

Response 200

{
  "breached": true,
  "breach_count": 2,
  "breaches": [
    {
      "name": "ExampleBreach",
      "date": "2024-01-15",
      "data_types": ["email", "password"]
    }
  ]
}

Métodos de Autenticação

A API v2 suporta três métodos de autenticação:

  1. API Key: Authorization: Bearer sk_xxxxx
    Obtenha a sua chave nas definições da conta. Ideal para integrações e scripts.
  2. JWT (JSON Web Token): Authorization: Bearer eyJxxx
    Obtido via POST /api/v2/auth/login/. Expira em 15 minutos; renove com /api/v2/auth/refresh/.
  3. Sessão (Cookie): Cookies de sessão Django, usados automaticamente pelo browser após login.

Exemplos — API v2

cURL — Login + Criar Cofre + Adicionar Item

# 1. Login
TOKEN=$(curl -s -X POST https://partilhar.link/api/v2/auth/login/ \
  -H "Content-Type: application/json" \
  -d '{"email": "eu@exemplo.com", "password": "a-minha-password"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['access'])")

# 2. Criar cofre
curl -X POST https://partilhar.link/api/v2/vaults/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name": "Pessoal", "description": "As minhas credenciais"}'

# 3. Adicionar item ao cofre
curl -X POST https://partilhar.link/api/v2/vaults/pessoal/items/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "item_type": "login",
    "encrypted_data": "base64-dados-encriptados...",
    "data_iv": "base64-iv...",
    "domain": "github.com",
    "title_hint": "GitHub"
  }'

Python — Fluxo completo

import requests

BASE = "https://partilhar.link/api/v2"

# Login
r = requests.post(f"{BASE}/auth/login/", json={
    "email": "eu@exemplo.com",
    "password": "a-minha-password",
})
tokens = r.json()
headers = {"Authorization": f"Bearer {tokens['access']}"}

# Criar cofre
r = requests.post(f"{BASE}/vaults/", json={
    "name": "Trabalho",
    "description": "Credenciais de trabalho",
}, headers=headers)
cofre = r.json()
print(f"Cofre criado: {cofre['slug']}")

# Adicionar item
r = requests.post(f"{BASE}/vaults/{cofre['slug']}/items/", json={
    "item_type": "login",
    "encrypted_data": "base64...",
    "data_iv": "base64...",
    "domain": "gitlab.com",
    "title_hint": "GitLab",
}, headers=headers)
print(f"Item criado: {r.json()['id']}")

# Verificar saúde
r = requests.get(f"{BASE}/health/", headers=headers)
print(f"Score de saúde: {r.json()['score']}")

JavaScript (fetch com JWT)

// Login
const loginRes = await fetch('https://partilhar.link/api/v2/auth/login/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'eu@exemplo.com',
    password: 'a-minha-password',
  })
});
const { access } = await loginRes.json();

// Headers autenticados
const authHeaders = {
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${access}`,
};

// Listar cofres
const vaultsRes = await fetch('https://partilhar.link/api/v2/vaults/', {
  headers: authHeaders,
});
const vaults = await vaultsRes.json();
console.log('Cofres:', vaults);

// Adicionar item ao primeiro cofre
const slug = vaults[0].slug;
const itemRes = await fetch(`https://partilhar.link/api/v2/vaults/${slug}/items/`, {
  method: 'POST',
  headers: authHeaders,
  body: JSON.stringify({
    item_type: 'login',
    encrypted_data: 'base64...',
    data_iv: 'base64...',
    domain: 'github.com',
    title_hint: 'GitHub',
  })
});
const item = await itemRes.json();
console.log('Item criado:', item.id);
← Criar partilha
Privacidade Termos valuedate.io
© 2026 valuedate.io