Поделиться папкой с кодом
POST/api/v1/folders
- Доступ
- Ключ API
- Право
content:write
ZIP папки; сервер оставляет только текстовые файлы и перечисляет остальное в folder.skipped с причиной: зависимости, сборка, служебные папки, секреты (не сохраняются никогда), .gitignore из корня, недопустимые в Windows имена, слишком глубокие пути, большие файлы, совпадения имён без учёта регистра и не текст по содержимому. Сохранённое — новый ZIP; в квоту идут его байты. Доступ, срок, пароль и одноразовое открытие — как у файлов.
Пример запроса
curl -X POST "https://lac.pics/api/v1/folders" \
-H "Authorization: Bearer lac_api_YOUR_KEY" \
-H "Idempotency-Key: folder-2026-09-28-my-app-1" \
-F "file=@my-app.zip" \
-F "visibility=unlisted"Параметры
Заголовки
Idempotency-KeystringСлучайная строка из 16–128 латинских букв, цифр,
_и-, одна на файл. Повтор с тем же ключом и теми же данными вернёт уже загруженный файл (201) и не продлит его срок; квитанции хранятся не меньше 24 часов. Попытка ещё идёт — 409 сRetry-After; тот же ключ с другими данными — 409; файл уже удалён или истёк — 410. Без заголовка каждый запрос — новая загрузка.шаблон
^[A-Za-z0-9_-]{16,128}$
Тело запроса
multipart/form-dataобязательный
filestring · binaryобязательныйZIP папки, до 32 МБ: без пароля, с именами в UTF-8, без путей вроде
../. Имя архива без.zip— название, еслиtitleне передан.tagsstringМассив строк в JSON, например
["demo","nextjs"]; правила те же, что у тегов в JSON.не длиннее 2 048
titlestringНазвание, до 180 символов.
не длиннее 180
visibilitystringprivate— только ты;unlisted— все, у кого есть ссылка;public— ещё лента и профиль, нельзя вместе сoneTime(400ONE_TIME_NOT_PUBLIC). Не передано при создании — настройка аккаунта; при изменении — доступ прежний.значения:
"private""unlisted""public"ttlstringСрок хранения от момента запроса:
day,week,monthилиforever— без срока. После него ссылка перестаёт открываться, зашифрованные данные удаляются в фоне.значения:
"forever""day""week""month"passwordstringтолько в запросе8–128 символов. Пустая строка снимает пароль, без поля пароль не меняется. Хранится как Argon2id и не возвращается; смена закрывает доступ тем, кто уже открывал. В ленте, профилях и альбомах другие видят такой файл закрытой карточкой.
не длиннее 128 · шаблон
^(?:[\s\S]{8,128})?$oneTimebooleanФайл откроет только первый гость — не дольше 10 минут, включая перемотку видео. Твой просмотр и запросы GET/HEAD ссылку не тратят. Нельзя вместе с
public; в ленте, профилях и альбомах такой файл не показывается.по умолчанию false
Ответы
201Создано
CreatedFolderidstringобязательныйid файла.
titlestringобязательныйНазвание.
tagsмассив stringобязательныйТеги.
до 10 элементов · без повторов
originalNamestringИсходное имя файла.
typestringобязательныйIMAGE,VIDEO,PASTEилиFOLDER— папка с кодом.значения:
"IMAGE""VIDEO""PASTE""FOLDER"mimestringобязательныйMIME-тип сохранённого файла.
pasteFormatstringили nullФормат заметки.
значения:
"plain""markdown""code"pasteLanguagestringили nullЯзык подсветки заметки.
folderFilesintegerили nullУ папки с кодом — сколько в ней файлов; у остального null.
от 1
revisionintegerобязательныйРевизия текста заметки для правки.
от 1
accessVersionintegerобязательныйShare access version: 1 for a new file, raised by every change of visibility, password or one-time. From 2 on,
urlcarries it as ?v= so messengers build a fresh link card instead of the one they kept for the previous access.от 1
sizeinteger · int64обязательныйРазмер в байтах.
visibilitystringобязательныйДоступ:
private,unlistedилиpublic.значения:
"private""unlisted""public"allowDownloadbooleanобязательныйПоказывается ли кнопка скачивания.
passwordProtectedbooleanобязательныйЕсть ли пароль.
oneTimebooleanобязательныйОдноразовая ли ссылка.
consumedAtstring · date-timeили nullКогда одноразовая ссылка была открыта.
readExpiresAtstring · date-timeили nullДо какого момента открывший одноразовую ссылку может смотреть файл.
readMaxExpiresAtstring · date-timeили nullСамый поздний конец доступа по одноразовой ссылке.
hasVideoTextbooleanЕсть ли у видео субтитры или расшифровка.
videoTextRevisionintegerРевизия текста видео.
0–2 147 483 647
viewsintegerобязательныйЗасчитанные открытия гостями, без повторов в пределах доступа зрителя (обычно сутки). Просмотры владельца не считаются.
от 0
viewLimitintegerили nullЛимит просмотров (Pro) или null.
1–1 000 000
viewLimitReachedAtstring · date-timeили nullКогда лимит просмотров исчерпан; null, пока просмотры есть или лимита нет.
mediaStatusstringОбработка:
PROCESSING— идёт,READY— готово,FAILED— не удалась. Воспроизведение и превью — послеREADY; оригинал владелец может скачать и раньше, с?download=1.значения:
"PROCESSING""READY""FAILED"mediaErrorstringили nullПричина, если обработка не удалась.
widthintegerили nullШирина в пикселях.
heightintegerили nullВысота в пикселях.
durationMsintegerили nullДлительность видео в миллисекундах.
videoCodecstringили nullКодек видео.
hasAudiobooleanЕсть ли звук.
previewUrlstringили nullАдрес зашифрованного превью; доступ — как у самого файла.
expiresAtstring · date-timeили nullКогда файл и ссылка перестанут работать; null — без срока.
createdAtstring · date-timeобязательныйКогда создан.
urlstring · uriобязательныйСсылка на страницу файла.
mediaUrlstringобязательныйАдрес самого файла.
moderationHoldstringили nullАвтопроверка:
review— скрыт до решения модератора,blocked— скрыт модератором. Другие видят такой файл как приватный.значения:
"review""blocked"favoritebooleanВ избранном (в списках).
ownedbooleanСвой файл (в списках).
authorobjectАвтор.
3 поля
idstringid автора.
usernamestringНикнейм.
namestringИмя.
contentContentФайл.
то же, что Content выше
folderobjectобязательныйили nullWhat the server kept and left out. Null when an Idempotency-Key replay returns the folder made before.
5 полей
filesintegerобязательныйот 1
textBytesintegerобязательныйот 0
skippedмассив FolderSkipобязательныйSorted by path; the first 200.
до 200 элементов
FolderSkip4 поляpathstringобязательныйA file, or a whole folder when it ends with «/».
reasonstringобязательныйdependencies (node_modules, vendor of a package manager, .venv…), build (dist, build, out, target, .next, bin/obj of .NET, coverage, caches…), service (.git, .svn, .hg, .idea, .vs), secret (.env* except .env.example, *.pem, *.key, id_rsa*, credentials*, token files, or a private key inside), gitignore (the root .gitignore), name (a name Windows cannot create), path (too deep or long), large (a file over the size limit), duplicate (a name that differs only by case), binary (not UTF-8 text by its bytes).
значения:
"dependencies""build""service""secret""gitignore""name""path""large""duplicate""binary"filesintegerобязательныйот 1
sizeintegerобязательныйРазмер в байтах.
от 0
skippedFilesintegerобязательныйот 0
gitignorestringобязательныйWhether the root .gitignore was applied: none without a readable one, complex when its patterns needed too much work (then it is not applied at all).
значения:
"applied""none""complex"
- 401Нужен действующий ключ
- 403Нет права или функции тарифа
- 404Не найдено
- 408Тело запроса перестало приходить
- 409Конфликт
- 410Файл удалён или истёк
- 429Слишком много запросов
- 503Сервис занят или недоступен
Пример ответа
{
"id": "Xq3u9RkT0bLmA7cV2pWz1eFy",
"title": "capture",
"tags": [
"release"
],
"originalName": "capture.png",
"type": "IMAGE",
"mime": "image/png",
"pasteFormat": null,
"pasteLanguage": null,
"folderFiles": 1,
"revision": 1,
"accessVersion": 1,
"size": 482133,
"visibility": "unlisted",
"allowDownload": true,
"passwordProtected": false,
"oneTime": false,
"consumedAt": null,
"readExpiresAt": null,
"readMaxExpiresAt": null,
"hasVideoText": false,
"videoTextRevision": 0,
"views": 3,
"viewLimit": null,
"viewLimitReachedAt": null,
"mediaStatus": "READY",
"mediaError": null,
"width": 1920,
"height": 1080,
"durationMs": null,
"videoCodec": null,
"hasAudio": false,
"previewUrl": null,
"expiresAt": null,
"createdAt": "2026-09-27T09:30:00.000Z",
"url": "https://lac.pics/s/Xq3u9RkT0bLmA7cV2pWz1eFy",
"mediaUrl": "/api/media/Xq3u9RkT0bLmA7cV2pWz1eFy",
"moderationHold": null,
"favorite": false,
"owned": true,
"author": {
"id": "cmf8a1x2k0000q7lh3v9w2e4d",
"username": "alex",
"name": "Alex"
},
"folder": {
"files": 1,
"textBytes": 0,
"skipped": [
{
"path": "string",
"reason": "dependencies",
"files": 1,
"size": 482133
}
],
"skippedFiles": 0,
"gitignore": "applied"
}
}Коды ошибок
| Код | Статус | Текст |
|---|---|---|
FOLDER_ARCHIVE_INVALID | 400 | Не удалось прочитать архив папки: нужен обычный ZIP без пароля, с именами в UTF-8 и без путей вроде «../». |
FOLDER_EMPTY | 400 | В папке не осталось файлов для загрузки: зависимости, сборка, секреты и не текст не загружаются. |
ONE_TIME_NOT_PUBLIC | 400 | Одноразовый файл нельзя опубликовать в ленте и профиле. Выбери доступ по ссылке или отключи одноразовую ссылку. |
FOLDER_TOO_LARGE | 413 | Текста в папке больше 20 МБ. Выбери папку поменьше или исключи лишнее в .gitignore. |
FOLDER_TOO_MANY_FILES | 413 | Можно до 2 000 файлов. Выбери папку поменьше или исключи лишнее в .gitignore. |
UPLOAD_TOO_LARGE | 413 | Файл больше допустимого размера. |
FOLDER_INFECTED | 422 | Антивирус нашёл угрозу в папке, поэтому она не загружена. |
Ответы любого метода с ключом — неверный или истёкший ключ, нет права, частые запросы — в разделе Ошибки.