files

Files

Signed upload/download URLs for object storage.

5 نقاط النهاية

DELETE /api/v1/files/{id}

Delete a file: removes the storage object and the row. Audited.

يتطلّب المصادقةالصلاحيةfiles.write

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/files/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200The file was deleted.

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/files/{id}

Get file metadata plus a short-lived (5 min) signed download URL.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/files/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
kindمطلوب
enum: "avatar" | "document" | "report" | "attachment"—
originalNameمطلوب
string—
mimeTypeمطلوب
string—
sizeBytesمطلوب
integer-9007199254740991–9007199254740991
sha256مطلوب
string—
entityTypeمطلوب
string | null≥1 chars
entityIdمطلوب
string (uuid) | null—
createdAtمطلوب
string (date-time)—
downloadUrlمطلوب
string—
downloadUrlExpiresAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "kind": "avatar",
  "originalName": "string",
  "mimeType": "string",
  "sizeBytes": -9007199254740991,
  "sha256": "string",
  "entityType": "string",
  "entityId": "81693677-8169-7169-8693-816936778169",
  "createdAt": "2026-03-02T09:00:00.000Z",
  "downloadUrl": "string",
  "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/files/complete

Finalize an upload after the client has PUT the object to its signed URL.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
fileId
string (uuid)—
storageKeyمطلوب
string1–1024 chars
sha256مطلوب
string—
kindمطلوب
enum: "avatar" | "document" | "report" | "attachment"—
originalNameمطلوب
string1–255 chars
mimeTypeمطلوب
enum: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | "application/pdf" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "text/csv"—
sizeBytesمطلوب
integer1–20971520
entityType
string1–100 chars
entityId
string (uuid)—

مثال

json
{
  "fileId": "0daca32e-0dac-7dac-8aca-0daca32e0dac",
  "storageKey": "string",
  "sha256": "string",
  "kind": "avatar",
  "originalName": "string",
  "mimeType": "image/jpeg",
  "sizeBytes": 1,
  "entityType": "string",
  "entityId": "81693677-8169-7169-8693-816936778169"
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/files/complete" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "fileId": "0daca32e-0dac-7dac-8aca-0daca32e0dac",
    "storageKey": "string",
    "sha256": "string",
    "kind": "avatar",
    "originalName": "string",
    "mimeType": "image/jpeg",
    "sizeBytes": 1,
    "entityType": "string",
    "entityId": "81693677-8169-7169-8693-816936778169"
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
kindمطلوب
enum: "avatar" | "document" | "report" | "attachment"—
originalNameمطلوب
string—
mimeTypeمطلوب
string—
sizeBytesمطلوب
integer-9007199254740991–9007199254740991
sha256مطلوب
string—
entityTypeمطلوب
string | null≥1 chars
entityIdمطلوب
string (uuid) | null—
createdAtمطلوب
string (date-time)—
downloadUrlمطلوب
string—
downloadUrlExpiresAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "kind": "avatar",
  "originalName": "string",
  "mimeType": "string",
  "sizeBytes": -9007199254740991,
  "sha256": "string",
  "entityType": "string",
  "entityId": "81693677-8169-7169-8693-816936778169",
  "createdAt": "2026-03-02T09:00:00.000Z",
  "downloadUrl": "string",
  "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/files/upload-url

Get a signed URL to upload a new file directly to storage (PUT the object to `uploadUrl`).

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
kindمطلوب
enum: "avatar" | "document" | "report" | "attachment"—
originalNameمطلوب
string1–255 chars
mimeTypeمطلوب
enum: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | "application/pdf" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "text/csv"—
sizeBytesمطلوب
integer1–20971520

مثال

json
{
  "kind": "avatar",
  "originalName": "string",
  "mimeType": "image/jpeg",
  "sizeBytes": 1
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/files/upload-url" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "kind": "avatar",
    "originalName": "string",
    "mimeType": "image/jpeg",
    "sizeBytes": 1
  }'

الاستجابات

201
الاسمالنوعالقيود
storageKeyمطلوب
string—
uploadUrlمطلوب
string—
expiresAtمطلوب
string (date-time)—
json
{
  "storageKey": "string",
  "uploadUrl": "string",
  "expiresAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/storage/usage

This institute’s used storage and, when the server can tell, how much room it still allows (the storage meter).

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/storage/usage" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
usedBytesمطلوب
integer0–9007199254740991
limitBytesمطلوب
integer | null0–9007199254740991
remainingBytesمطلوب
integer | null0–9007199254740991
serverTotalBytesمطلوب
integer | null0–9007199254740991
serverAvailableBytesمطلوب
integer | null0–9007199254740991
reserveBytesمطلوب
integer | null0–9007199254740991
capEnabledمطلوب
boolean—
json
{
  "usedBytes": 0,
  "limitBytes": 0,
  "remainingBytes": 0,
  "serverTotalBytes": 0,
  "serverAvailableBytes": 0,
  "reserveBytes": 0,
  "capEnabled": true
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.