
## Public object metadata

`HEAD /v1/public-storage/:portalId/:objectId`

Returns the metadata of a completed (`COMPLETED`) publicly accessible object in the response headers without transferring the content. `PENDING` objects are not served and return `404 STORAGE_OBJECT_NOT_FOUND` without the metadata headers of a successful response. No API key is required — the endpoint is anonymous. Anonymous access is enabled separately at the Bitrix24 account level and is off by default.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `portalId` (path) | string (UUID) | yes | The Bitrix24 portal identifier in Vibecode. Format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`. Source: [`GET /v1/me`](/docs/keys-auth/me) — the `data.portalId` field for `vibe_api_` and `vibe_app_` keys, `data.portals[n].id` for a `vibe_live_` management key |
| `objectId` (path) | string (CUID) | yes | Internal object identifier: the `object.id` field from the [Direct file upload](/docs/storage/upload/direct) response or `data[].id` from the [List objects](/docs/storage/objects/list) response |

## Examples

**No key required.** Both examples are sent without authorization headers — this is an anonymous endpoint.

### curl

```bash
curl -I "https://vibecode.bitrix24.com/v1/public-storage/YOUR_PORTAL_ID/YOUR_OBJECT_ID"
```

### JavaScript

```javascript
const res = await fetch(
  'https://vibecode.bitrix24.com/v1/public-storage/YOUR_PORTAL_ID/YOUR_OBJECT_ID',
  { method: 'HEAD' }
)
if (res.ok) {
  console.log('MIME type:', res.headers.get('content-type'))
  console.log('Size:', res.headers.get('content-length'))
}
```

## Response fields

The behavior depends on the state of anonymous access in the Bitrix24 account:

**Anonymous access enabled in the Bitrix24 account.** For a completed `PUBLIC` object, the server returns `200 OK` with the following headers:

| Header | Value |
|-----------|---------|
| `Content-Type` | The object's content MIME type |
| `Content-Length` | The object's size in bytes |
| `Cache-Control` | `private, no-store` |

There is no response body.

**Anonymous access disabled in the Bitrix24 account** (the default for a new Bitrix24 account): `503 STORAGE_PUBLIC_GET_DISABLED_FOR_PORTAL`. It is enabled by the Bitrix24 account administrator.

## Response example

Anonymous access is enabled in the Bitrix24 account and the object is `PUBLIC`:

```http
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 303
Cache-Control: private, no-store
```

## Error response example

503 — anonymous access disabled in the Bitrix24 account:

```json
{
  "success": false,
  "error": {
    "code": "STORAGE_PUBLIC_GET_DISABLED_FOR_PORTAL",
    "message": "Public storage GET is disabled for this portal"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 404 | `STORAGE_OBJECT_NOT_FOUND` | The upload is incomplete (`PENDING`), the object is missing, has `PRIVATE` visibility, belongs to another portal, or `objectId` does not match any object |
| 410 | `STORAGE_OBJECT_DELETED` | The completed object was deleted |
| 429 | `STORAGE_RATE_LIMIT_EXCEEDED` | Exceeded the limit of 60 requests per minute from a single IP address. The current limit is returned in the `x-ratelimit-limit` header |
| 503 | `STORAGE_PUBLIC_GET_DISABLED_FOR_PORTAL` | Anonymous access is disabled in this portal |
| 503 | `STORAGE_FEATURE_DISABLED` | Storage is temporarily unavailable on the platform |

For the full list of general API errors, see [Errors](/docs/errors).

## Known specifics

- **Anonymous access is enabled separately.** Even a completed object with `PUBLIC` visibility does not automatically become available through this endpoint — the Bitrix24 account administrator must enable anonymous access in the storage settings.
- **`objectId` is the internal identifier, not the logical key.** Use the `object.id` field from the [Direct file upload](/docs/storage/upload/direct) response or `data[].id` from the [List objects](/docs/storage/objects/list) response.
- **The `Content-Length` header contains the object's real size** from the database — not the length of the serialized response.

## See also

- [Public access GET](/docs/storage/objects/public-get)
- [Object metadata (authorized)](/docs/storage/objects/head)
- [List objects](/docs/storage/objects/list)
- [Delete object](/docs/storage/objects/delete)
