Archivos de tu app
Forja guarda las fotos, los PDF y otros archivos de tu app aparte de tus tablas. Los archivos suben y bajan directo contra el almacenamiento con direcciones firmadas que duran unos minutos, así que nunca quedan abiertos por accidente.
Cómo se ve en el dashboard. En el proyecto, Archivos muestra lo que hay guardado, cuánto espacio usaste, y te deja subir, abrir, borrar y marcar archivos como públicos o privados sin escribir código.
Cómo funciona
- Tu app (o tu servidor) le pide a Forja subir un archivo: nombre, tipo y tamaño.
- Forja revisa que el tipo esté permitido y que entre en tu espacio, y devuelve una dirección firmada para subirlo.
- Quien sube manda los bytes a esa dirección con un
PUT. Los bytes no pasan por Forja. - Avisa a Forja con
POST …/complete. Forja comprueba que el archivo llegó completo y que sus primeros bytes corresponden al tipo declarado: un ejecutable renombrado a.pngse descarta.
Antes de empezar
- Para subir desde tu servidor, creá una llave privada con el permiso Archivos enLlaves y permisos. Las llaves de staging y las públicas (las que van en una página) no pueden tenerlo.
- Para que las personas que usan tu app suban y vean archivos con su sesión, configurá primero ellogin de usuarios y después, en Archivos → Archivos de las personas de tu app, elegí qué pueden hacer y los topes de espacio (más abajo).
Subir un archivo
POST https://api.getforja.site/v1/files
Authorization: Bearer fk_live_…
Content-Type: application/json
{ "name": "comprobante.pdf", "contentType": "application/pdf", "size": 184233 }{
"file": { "id": "9d1f…", "name": "comprobante.pdf", "contentType": "application/pdf", "size": 184233, "visibility": "PRIVATE", "createdAt": "…", "publicUrl": null },
"upload": {
"url": "https://…",
"method": "PUT",
"headers": { "Content-Type": "application/pdf" },
"expiresAt": "2026-11-02T12:10:00.000Z"
}
}El PUT tiene que usar exactamente los headers que devuelve Forja (el Content-Type va firmado: con otro tipo, el almacenamiento lo rechaza). La dirección de subida vale 10 minutos. Funciona desde un navegador, de cualquier sitio.
const API = "https://api.getforja.site";
const LLAVE = "fk_live_…"; // solo en tu servidor: esta llave no va en una página
async function subirArchivo(archivo) {
// 1) Pedí la subida: Forja revisa el tipo, el tamaño y tu espacio, y te da una dirección firmada.
const pedido = await fetch(API + "/v1/files", {
method: "POST",
headers: { Authorization: "Bearer " + LLAVE, "Content-Type": "application/json" },
body: JSON.stringify({ name: archivo.name, contentType: archivo.type, size: archivo.size }),
});
if (!pedido.ok) throw new Error((await pedido.json()).error);
const { file, upload } = await pedido.json();
// 2) Mandá los bytes directo a esa dirección. No pasan por Forja.
const envio = await fetch(upload.url, { method: upload.method, headers: upload.headers, body: archivo });
if (!envio.ok) throw new Error("No se pudo subir el archivo");
// 3) Avisá a Forja que terminaste: ahí comprueba que llegó completo y que es lo que dice ser.
const fin = await fetch(API + "/v1/files/" + file.id + "/complete", {
method: "POST",
headers: { Authorization: "Bearer " + LLAVE },
});
if (!fin.ok) throw new Error((await fin.json()).error);
return (await fin.json()).file;
}Bajar y mostrar un archivo
Un archivo privado se baja con una dirección firmada que dura 15 minutos:
GET https://api.getforja.site/v1/files/<ID_DEL_ARCHIVO>/url
Authorization: Bearer fk_live_…
→ { "url": "https://…", "expiresAt": "2026-11-02T12:15:00.000Z" }Las imágenes y los PDF se abren en el navegador; todo lo demás se baja como adjunto. Forja siempre responde con el tipo que validó, nunca con el que adivine el navegador.
Archivos públicos
Un archivo público tiene una dirección estable que se puede usar en un <img> o en un enlace, sin llave. Forja no entrega los bytes: la dirección redirige a una dirección firmada y los entrega el almacenamiento.
<img src="https://api.getforja.site/v1/files/<ID_DEL_PROYECTO>/<ID_DEL_ARCHIVO>/public" alt="Logo" />- En Free pueden ser públicas las imágenes (JPG, PNG, GIF, WebP, AVIF): lo que más se muestra en una página. PDF, audio, video y los demás tipos pueden ser públicos desde Starter; en Free se quedan privados y los mostrás con una dirección firmada.
- Marcá un archivo como público al subirlo (
"visibility": "PUBLIC") o después, conPATCH /v1/files/<id>. - Cualquiera que tenga la dirección puede abrir el archivo. Usalo solo para lo que de verdad puede ver todo el mundo.
- Si el archivo se borra, se vuelve privado o Forja lo da de baja, la dirección responde 404.
Que las personas de tu app suban y vean archivos
Las personas que inician sesión en tu app pueden usar los mismos caminos con su accessToken, sin llave de API y sin servidor intermedio. Por defectono pueden nada: vos encendés el acceso y elegís qué pueden hacer.
// Con la sesión de la persona (accessToken del login de tu app), sin llave de API.
// Es el mismo camino de arriba, solo cambia el encabezado:
Authorization: Bearer <accessToken de la persona>| Regla | Opciones |
|---|---|
| Subir | sí (queda a su nombre) o no |
| Ver | solo los que subió ella, todos los del proyecto, o ninguno |
| Borrar | solo los suyos, o ninguno |
| Dejar públicos sus archivos | sí o no (en Free, solo imágenes) |
Lo que sube una persona gasta tu espacio. Por eso, al encender el acceso tenés que elegir tres topes, y Forja propone valores razonables:
- Espacio y cantidad de archivos por persona. Al llegar, esa persona no puede subir más hasta borrar algo.
- Espacio de todas las personas juntas. Es tu defensa contra cuentas falsas: cuando se llena, nadie más sube, y el resto de tu espacio queda para lo que sube tu servidor.
- Cada persona puede tener además hasta 5 subidas sin terminar a la vez.
Recomendamos pedir que confirmen su correo antes de entrar (en Usuarios de la app). Las personas nunca ven nada de tu plan: solo reciben mensajes genéricos como "llegaste al espacio que tiene esta app para vos".
Desde un navegador, el pedido solo se acepta desde los sitios autorizados del login. Una persona nunca puede tocar los archivos de otra, salvo que la regla de ver sea "todos".
Qué tipos de archivo se aceptan
Imágenes (JPG, PNG, GIF, WebP, AVIF), PDF, texto, CSV, JSON, audio (MP3, OGG, WAV, M4A), video (MP4, WebM), zip y documentos de Office (Word, Excel, PowerPoint).Nunca se aceptan HTML, SVG, JavaScript, ejecutables ni scripts, en ningún plan: un archivo de esos podría usarse para estafas o para ejecutar código en el navegador de quien lo abre.
Límites por plan
| Plan | Espacio | Máximo por archivo | Archivos públicos |
|---|---|---|---|
| Free | 250 MB | 5 MB | Solo imágenes |
| Starter | 5 GB | 50 MB | Cualquier tipo permitido |
| Growth | 50 GB | 200 MB | Cualquier tipo permitido |
| Enterprise | a medida | a medida | Cualquier tipo permitido |
El espacio es por cuenta, sumando todos tus proyectos. Los precios están en Precios. Si llegás al tope, no se pueden subir archivos nuevos, pero seguís pudiendo listar, bajar y borrar. Si bajás de plan con más archivos que el espacio nuevo, no se borra nada: solo se bloquean las subidas.
Referencia de rutas
Todas cuelgan de https://api.getforja.site. Aceptan una llave privada con el permiso Archivos o la sesión de una persona de tu app.
| Ruta | Qué hace |
|---|---|
POST /v1/files | Pide subir un archivo. Devuelve el archivo reservado y la dirección de subida. |
POST /v1/files/<id>/complete | Termina la subida: comprueba tamaño y contenido. |
GET /v1/files | Lista los archivos (limit hasta 100 y offset). |
GET /v1/files/<id> | Los datos de un archivo. |
GET /v1/files/<id>/url | Una dirección firmada para bajarlo (15 minutos). |
PATCH /v1/files/<id> | Cambia la visibilidad: { "visibility": "PUBLIC" } o "PRIVATE". |
DELETE /v1/files/<id> | Borra el archivo (responde 204). |
GET /v1/files/<proyecto>/<id>/public | La dirección estable de un archivo público. No lleva llave. |
Errores
Los errores traen un texto en español en error y un code estable.
| Código HTTP | code | Cuándo |
|---|---|---|
| 403 | FILES_NOT_AVAILABLE | Los archivos todavía no están disponibles en tu cuenta. |
| 403 | FILES_LIMIT_REACHED | Llegaste al espacio de tu plan. |
| 403 | PUBLIC_FILES_NOT_INCLUDED | Tu plan no permite una dirección pública para ese tipo de archivo (en Free, solo imágenes). |
| 403 | USER_ACTION_NOT_ALLOWED | Las reglas de tu app no le permiten eso a esa persona. |
| 403 | FILES_USER_LIMIT_REACHED, FILES_APP_USERS_LIMIT_REACHED | Una persona, o todas juntas, llegaron a los topes que elegiste. |
| 404 | FILE_NOT_FOUND | No existe, no es tuyo, o fue dado de baja. |
| 409 | FILE_NOT_UPLOADED | Llamaste a complete antes de terminar de subir. |
| 413 | FILE_TOO_LARGE | Pesa más que el máximo por archivo de tu plan. |
| 415 | FILE_TYPE_NOT_ALLOWED | Es un tipo que Forja no guarda. |
| 422 | FILE_SIZE_MISMATCH, FILE_CONTENT_MISMATCH | Pesa distinto de lo declarado, o no es del tipo que dice ser. Se descarta: pedí una subida nueva. |
| 429 | TOO_MANY_PENDING_UPLOADS | Una persona tiene demasiadas subidas sin terminar. |
Qué no incluye todavía
- Redimensionar o recortar imágenes, ni generar miniaturas.
- Revisión de virus o de contenido: Forja comprueba el tipo, no examina lo que hay adentro.
- Exportar los archivos: la exportación del proyecto trae tus tablas y funciones, pero no los archivos. Si algún día migrás, bajalos con la API.
- Un dominio propio para las direcciones públicas: salen de
api.getforja.sitey redirigen al almacenamiento. - Archivos de staging: existen solo en producción.
- Reemplazar el contenido de un archivo: se sube uno nuevo y se borra el anterior.
Contenido que se puede guardar
Sos responsable de lo que guardan vos y las personas de tu app. Forja puede dar de baja un archivo ante una denuncia o un abuso, y suspender una cuenta que lo repita. Las reglas de uso aceptable están en los Términos; para denunciar un archivo, escribí asoporte@getforja.site con su dirección o identificador y el motivo.
Esta lista y otras están en Qué no hace todavía.
Información revisada el 2026-11-02.