# Create File

Registers a new file from a publicly accessible URL, optionally tagging it. The file is fetched, checked against the supported formats and the size limit, and stored.
## Authentication
Requires a valid API key in the `X-API-KEY` header.
## Request Body

```json
{
  "url": "https://example.com/docs/product-datasheet.pdf",
  "tags": ["datasheets", "catalog", "summer-2024"]
}
```
### URL Field (Required)
The URL must meet the following requirements:
**Valid URL formats:**
- Must be a valid HTTP or HTTPS URL
- Must be absolute (e.g., `https://example.com/manual.pdf`)
- Relative URLs are NOT supported (e.g., `/docs/manual.pdf`)
- The filename is taken from the URL path and becomes the file's `reference`

**Examples of valid URLs:**

```
https://example.com/product-datasheet.pdf
https://cdn.example.com/docs/2024/manual.docx
http://assets.example.com/exports/catalog_123.csv
```
**Examples of invalid URLs:**

```
/docs/manual.pdf                       (relative URL)
example.com/manual.pdf                 (missing protocol)
ftp://server.com/manual.pdf            (FTP not supported)
https://example.com/installer.exe      (extension not accepted)
https://example.com/datasheet          (no extension to derive the file type from)
```
**URL validation rules:**
- Maximum length: 2048 characters
- The file name at the end of the URL path becomes the file's `reference` and may be no longer
than 255 characters, extension excluded
- The URL must be publicly accessible (no authentication supported)
- The host must resolve to a public address. URLs pointing at loopback, private ranges or the
cloud metadata endpoint are rejected
- The URL is probed with a `HEAD` request; anything other than a 2xx is rejected
- An address that never answers, or that refuses the connection, is rejected the same way — as an
address the caller has to correct, not as a technical error

### Tags Field (Optional)
Optional array of strings to categorize and organize your files.
**Rules:**
- Each tag cannot be empty or contain only whitespace
- Tags are case-sensitive
- No tag may contain a comma. A comma is the separator the set is stored with, so a tag carrying
one would be read back as two; it is rejected rather than accepted and mangled
- There is no explicit limit on the number of tags, but the whole comma-separated list must fit in
64 KB of storage

## Supported File Formats
The file type is taken from the URL's file extension and must be one of:
| Category | Extensions |
|  --- | --- |
| Documents | `pdf`, `doc`, `docx`, `txt`, `rtf`, `odt` |
| Spreadsheets | `xls`, `xlsx`, `csv`, `ods` |
| Presentations | `ppt`, `pptx`, `odp` |
| Archives | `zip`, `rar`, `7z`, `tar`, `gz`, `tgz` |
| Video and audio | `mp4`, `mov`, `webm`, `m4v`, `mpeg`, `mpg`, `avi`, `mp3`, `wav` |
| Images | `jpg`, `jpeg`, `png`, `gif`, `bmp`, `tif`, `tiff`, `psd`, `webp`, `avif`, `heic` |
| Markup and data | `svg`, `html`, `htm`, `xml`, `json` |
| Print production | `ai`, `eps`, `indd`, `idml`, `idms` |
| CAD, BIM and 3D | `dwg`, `dxf`, `step`, `stp`, `iges`, `igs`, `stl`, `sat`, `obj`, `mtl`, `fbx`, `3ds`, `max`, `skp`, `glb`, `gltf`, `usdz`, `dae`, `3dm`, `x3d`, `ifc`, `rfa`, `rvt`, `iam`, `ipt`, `idw` |
| Photometry and product data | `ldt`, `ies`, `uld`, `gll`, `gdtf`, `bc3`, `bom`, `sup` |
| Fonts | `otf`, `ttf`, `woff`, `woff2` |

The extension is matched case-insensitively and decides which format the file is filed as. The
`Content-Type` the URL serves is **not** validated, unlike `POST /images`: several of the accepted
formats have no registered media type and are commonly served as `application/octet-stream`, so a
media-type allow-list would reject valid uploads without excluding anything.
## File Size Limit
- **Maximum file size:** 250 MB (262,144,000 bytes)
- The transfer is cut off as soon as the limit is exceeded, so an oversized file is never stored

## Response
### Success Response (201 Created)
Returns the reference (filename) of the created file, wrapped in the house entity envelope. The
reference is the public, tenant-unique key; the numeric id is internal only and is not exposed:

```json
{
  "value": {
    "reference": "product-datasheet.pdf"
  },
  "@readLink": "https://api2.saleslayer.com/dam/files(product-datasheet.pdf)",
  "@editLink": "https://api2.saleslayer.com/dam/files(product-datasheet.pdf)"
}
```
## Error Responses
### 400 Bad Request
Validation failures are returned in the shared envelope. Service-level messages carry no field
context, so they are grouped under a generic `error` key:

```json
{
  "validationFailures": {
    "error": ["URL is required"]
  }
}
```
The messages you can receive, verbatim:
| Cause | Message |
|  --- | --- |
| Missing or empty URL | `URL is required` |
| URL over 2048 characters | `URL exceeds maximum length of 2048 characters` |
| Not an absolute URL | `URL is not valid` |
| Scheme other than HTTP/HTTPS | `URL must use HTTP or HTTPS protocol` |
| No extension in the URL path | `Could not determine file type from URL. Please ensure the URL contains a filename with an extension.` |
| Unsupported extension | `File extension 'exe' is not allowed. Allowed extensions: 3dm, 3ds, 7z, ai, avi, ...` — the whole accepted set, alphabetically |
| File name over 255 characters (extension excluded) | `File name exceeds maximum length of 255 characters` |
| Host is not publicly routable | `URL host 'localhost' is not allowed.` |
| URL not reachable (non-2xx `HEAD`) | `URL is not accessible. HTTP status: 404 Not Found` |
| URL did not answer in time | `URL is not accessible. The address did not respond in time.` |
| Connection refused, DNS or TLS failure | `URL is not accessible. The address 'cdn.example.com' could not be reached.` |
| Empty file | `The uploaded file is empty` |
| Stored copy missing | `The uploaded file could not be found in storage.` |
| File too large | `File size (300.00 MB) exceeds maximum allowed size of 250 MB` |
| Content is a different file type | `The address serves a PNG image, but the file name 'product-datasheet.pdf' announces a 'pdf' file.` |
| Content matches no known file type | `The address does not serve a 'pdf' file: its content matches no known file type.` |
| Empty or whitespace-only tag | `Tags cannot contain empty values` |
| Tag containing a comma | `Tags cannot contain commas` |

### 401 Unauthorized
Missing or invalid API key in the `X-API-KEY` header. Emitted by the API gateway:

```json
{
  "message": "Unauthorized",
  "request_id": "d8aafa5b8f3e400b60bea0123dd33317"
}
```
### 403 Forbidden
The API key does not have write permissions for this operation. Same body shape as the 401.
### 409 Conflict
Two distinct causes, both using the conflict envelope:
**A file with the same filename (`reference`) already exists for this tenant:**

```json
{
  "error": "A file with the filename 'product-datasheet.pdf' already exists"
}
```
**The tenant has reached its file-library quota:**

```json
{
  "error": "File library limit reached. Current: 500, Maximum: 500"
}
```
Deleted files do not count towards the quota. Delete unused files to free
capacity, or contact Sales Layer to raise the limit. The file and image libraries have separate
quotas, so files never consume image capacity or vice versa.
## Complete Example
**Request:**

```http
POST /files HTTP/1.1
Host: api2.saleslayer.com
X-API-KEY: your-api-key-here
Content-Type: application/json
            
{
  "url": "https://cdn.example.com/docs/2024/product-datasheet.pdf",
  "tags": ["datasheets", "catalog"]
}
```
**Success Response:**

```http
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://api2.saleslayer.com/dam/files(product-datasheet.pdf)
            
{
  "value": {
    "reference": "product-datasheet.pdf"
  }
}
```
**Result:**

```json
{
  "value": {
    "reference": "product-datasheet.pdf",
    "status": "Ok",
    "fileType": "pdf",
    "sizeInBytes": 524288,
    "numLinks": 0,
    "tags": ["datasheets", "catalog"],
    "url": "https://cdn.example.com/CMP2009/files/product-datasheet.pdf",
    "createdOn": "2024-04-02T10:30:00Z",
    "modifiedOn": "2024-04-02T10:30:00Z"
  }
}
```

Endpoint: POST /files
Version: 2.0.0

## Description:

  - `Authentication` ()
    Requires a valid API key in the X-API-KEY header.

  - `Request Body` ()
    {
  "url": "https://example.com/docs/product-datasheet.pdf",
  "tags": ["datasheets", "catalog", "summer-2024"]
}
{
  "url": "https://example.com/docs/product-datasheet.pdf",
  "tags": ["datasheets", "catalog", "summer-2024"]
}

  - `URL Field (Required)` ()
    The URL must meet the following requirements: Valid URL formats: Must be a valid HTTP or HTTPS URLMust be absolute (e.g., https://example.com/manual.pdf)Relative URLs are NOT supported (e.g., /docs/manual.pdf)The filename is taken from the URL path and becomes the file's reference Examples of valid URLs: https://example.com/product-datasheet.pdf
https://cdn.example.com/docs/2024/manual.docx
http://assets.example.com/exports/catalog_123.csv
https://example.com/product-datasheet.pdf
https://cdn.example.com/docs/2024/manual.docx
http://assets.example.com/exports/catalog_123.csv Examples of invalid URLs: /docs/manual.pdf                       (relative URL)
example.com/manual.pdf                 (missing protocol)
ftp://server.com/manual.pdf            (FTP not supported)
https://example.com/installer.exe      (extension not accepted)
https://example.com/datasheet          (no extension to derive the file type from)
/docs/manual.pdf                       (relative URL)
example.com/manual.pdf                 (missing protocol)
ftp://server.com/manual.pdf            (FTP not supported)
https://example.com/installer.exe      (extension not accepted)
https://example.com/datasheet          (no extension to derive the file type from) URL validation rules: Maximum length: 2048 charactersThe file name at the end of the URL path becomes the file's reference and may be no longerthan 255 characters, extension excludedThe URL must be publicly accessible (no authentication supported)The host must resolve to a public address. URLs pointing at loopback, private ranges or thecloud metadata endpoint are rejectedThe URL is probed with a HEAD request; anything other than a 2xx is rejectedAn address that never answers, or that refuses the connection, is rejected the same way — as anaddress the caller has to correct, not as a technical error

  - `Tags Field (Optional)` ()
    Optional array of strings to categorize and organize your files. Rules: Each tag cannot be empty or contain only whitespaceTags are case-sensitiveNo tag may contain a comma. A comma is the separator the set is stored with, so a tag carryingone would be read back as two; it is rejected rather than accepted and mangledThere is no explicit limit on the number of tags, but the whole comma-separated list must fit in64 KB of storage

  - `Supported File Formats` ()
    The file type is taken from the URL's file extension and must be one of: CategoryExtensionsDocumentspdf, doc, docx, txt, rtf, odtSpreadsheetsxls, xlsx, csv, odsPresentationsppt, pptx, odpArchiveszip, rar, 7z, tar, gz, tgzVideo and audiomp4, mov, webm, m4v, mpeg, mpg, avi, mp3, wavImagesjpg, jpeg, png, gif, bmp, tif, tiff, psd, webp, avif, heicMarkup and datasvg, html, htm, xml, jsonPrint productionai, eps, indd, idml, idmsCAD, BIM and 3Ddwg, dxf, step, stp, iges, igs, stl, sat, obj, mtl, fbx, 3ds, max, skp, glb, gltf, usdz, dae, 3dm, x3d, ifc, rfa, rvt, iam, ipt, idwPhotometry and product dataldt, ies, uld, gll, gdtf, bc3, bom, supFontsotf, ttf, woff, woff2 The extension is matched case-insensitively and decides which format the file is filed as. TheContent-Type the URL serves is not validated, unlike POST /images: several of the acceptedformats have no registered media type and are commonly served as application/octet-stream, so amedia-type allow-list would reject valid uploads without excluding anything.

  - `File Size Limit` ()
    Maximum file size: 250 MB (262,144,000 bytes)The transfer is cut off as soon as the limit is exceeded, so an oversized file is never stored

  - `Response` ()

  - `Success Response (201 Created)` ()
    Returns the reference (filename) of the created file, wrapped in the house entity envelope. Thereference is the public, tenant-unique key; the numeric id is internal only and is not exposed: {
  "value": {
    "reference": "product-datasheet.pdf"
  },
  "@readLink": "https://api2.saleslayer.com/dam/files(product-datasheet.pdf)",
  "@editLink": "https://api2.saleslayer.com/dam/files(product-datasheet.pdf)"
}
{
  "value": {
    "reference": "product-datasheet.pdf"
  },
  "@readLink": "https://api2.saleslayer.com/dam/files(product-datasheet.pdf)",
  "@editLink": "https://api2.saleslayer.com/dam/files(product-datasheet.pdf)"
}

  - `Error Responses` ()

  - `400 Bad Request` ()
    Validation failures are returned in the shared envelope. Service-level messages carry no fieldcontext, so they are grouped under a generic error key: {
  "validationFailures": {
    "error": ["URL is required"]
  }
}
{
  "validationFailures": {
    "error": ["URL is required"]
  }
} The messages you can receive, verbatim: CauseMessageMissing or empty URLURL is requiredURL over 2048 charactersURL exceeds maximum length of 2048 charactersNot an absolute URLURL is not validScheme other than HTTP/HTTPSURL must use HTTP or HTTPS protocolNo extension in the URL pathCould not determine file type from URL. Please ensure the URL contains a filename with an extension.Unsupported extensionFile extension 'exe' is not allowed. Allowed extensions: 3dm, 3ds, 7z, ai, avi, ... — the whole accepted set, alphabeticallyFile name over 255 characters (extension excluded)File name exceeds maximum length of 255 charactersHost is not publicly routableURL host 'localhost' is not allowed.URL not reachable (non-2xx HEAD)URL is not accessible. HTTP status: 404 Not FoundURL did not answer in timeURL is not accessible. The address did not respond in time.Connection refused, DNS or TLS failureURL is not accessible. The address 'cdn.example.com' could not be reached.Empty fileThe uploaded file is emptyStored copy missingThe uploaded file could not be found in storage.File too largeFile size (300.00 MB) exceeds maximum allowed size of 250 MBContent is a different file typeThe address serves a PNG image, but the file name 'product-datasheet.pdf' announces a 'pdf' file.Content matches no known file typeThe address does not serve a 'pdf' file: its content matches no known file type.Empty or whitespace-only tagTags cannot contain empty valuesTag containing a commaTags cannot contain commas

  - `401 Unauthorized` ()
    Missing or invalid API key in the X-API-KEY header. Emitted by the API gateway: {
  "message": "Unauthorized",
  "request_id": "d8aafa5b8f3e400b60bea0123dd33317"
}
{
  "message": "Unauthorized",
  "request_id": "d8aafa5b8f3e400b60bea0123dd33317"
}

  - `403 Forbidden` ()
    The API key does not have write permissions for this operation. Same body shape as the 401.

  - `409 Conflict` ()
    Two distinct causes, both using the conflict envelope: A file with the same filename (reference) already exists for this tenant: {
  "error": "A file with the filename 'product-datasheet.pdf' already exists"
}
{
  "error": "A file with the filename 'product-datasheet.pdf' already exists"
} The tenant has reached its file-library quota: {
  "error": "File library limit reached. Current: 500, Maximum: 500"
}
{
  "error": "File library limit reached. Current: 500, Maximum: 500"
} Deleted files do not count towards the quota. Delete unused files to freecapacity, or contact Sales Layer to raise the limit. The file and image libraries have separatequotas, so files never consume image capacity or vice versa.

  - `Complete Example` ()
    Request: POST /files HTTP/1.1
Host: api2.saleslayer.com
X-API-KEY: your-api-key-here
Content-Type: application/json
            
{
  "url": "https://cdn.example.com/docs/2024/product-datasheet.pdf",
  "tags": ["datasheets", "catalog"]
}
POST /files HTTP/1.1
Host: api2.saleslayer.com
X-API-KEY: your-api-key-here
Content-Type: application/json
            
{
  "url": "https://cdn.example.com/docs/2024/product-datasheet.pdf",
  "tags": ["datasheets", "catalog"]
} Success Response: HTTP/1.1 201 Created
Content-Type: application/json
Location: https://api2.saleslayer.com/dam/files(product-datasheet.pdf)
            
{
  "value": {
    "reference": "product-datasheet.pdf"
  }
}
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://api2.saleslayer.com/dam/files(product-datasheet.pdf)
            
{
  "value": {
    "reference": "product-datasheet.pdf"
  }
} Result: {
  "value": {
    "reference": "product-datasheet.pdf",
    "status": "Ok",
    "fileType": "pdf",
    "sizeInBytes": 524288,
    "numLinks": 0,
    "tags": ["datasheets", "catalog"],
    "url": "https://cdn.example.com/CMP2009/files/product-datasheet.pdf",
    "createdOn": "2024-04-02T10:30:00Z",
    "modifiedOn": "2024-04-02T10:30:00Z"
  }
}
{
  "value": {
    "reference": "product-datasheet.pdf",
    "status": "Ok",
    "fileType": "pdf",
    "sizeInBytes": 524288,
    "numLinks": 0,
    "tags": ["datasheets", "catalog"],
    "url": "https://cdn.example.com/CMP2009/files/product-datasheet.pdf",
    "createdOn": "2024-04-02T10:30:00Z",
    "modifiedOn": "2024-04-02T10:30:00Z"
  }
}

## Header parameters:

  - `X-API-KEY` (string, required)
    Tenant's API key (required)

## Request body:

  - `application/json, text/json, application/*+json` (unknown)
    Request containing the file URL and optional tags

## Request fields (application/json):

  - `url` (string)
    Publicly accessible HTTP or HTTPS URL of the file to import. Required. Must be absolute and end
in a supported extension (pdf, doc, docx, txt, xls, xlsx, csv, rtf, ppt, pptx, zip, rar, tar,
mpeg, mpg, avi, mov, tif, tiff, ai, eps, psd, x3d, sup, ldt, ies, dwg, obj, webp); the file's
`reference` is the filename taken from the URL path. Maximum 2048 characters.

  - `tags` (array)
    Optional tags to associate with the file, e.g. `["datasheets", "catalog", "2024"]`. Tags are
case-sensitive and cannot be empty or whitespace. Avoid commas inside a tag — tags are stored as a
comma-separated string and would be read back split.

## Response 201:

  - `201` (unknown)
    Created

## Response 201 fields (application/json):

  - `value` (object)
    The reference of a newly created file. Retrieve the full file with
`GET /files({reference})`. Unlike an image, a file is usable as soon as it is created — nothing
processes it afterwards — so it starts, and stays, in status `Ok`.

  - `value.reference` (string)
    The file's filename, unique per tenant. This is the public key used to address the file.

  - `@readLink` (string)
    Canonical URL of the created file, the same resource the `Location` header names.
Present only when hypermedia enrichment is enabled.

  - `@editLink` (string)
    URL to modify the created file, identical to `@readLink`. Present only when hypermedia
enrichment is enabled.

## Response 400:

  - `400` (unknown)
    Bad Request

## Response 400 fields (application/json):

  - `validationFailures` (object)

## Response 401:

  - `401` (unknown)
    Unauthorized

## Response 401 fields (application/json):

  - `message` (string)
    Error description, e.g. `Unauthorized`.

  - `request_id` (string)
    Gateway request identifier, to quote when contacting support.

## Response 403:

  - `403` (unknown)
    Forbidden

## Response 403 fields (application/json):

  - `message` (string)

  - `request_id` (string)

## Response 409:

  - `409` (unknown)
    Conflict

## Response 409 fields (application/json):

  - `error` (string)

## Response 500:

  - `500` (unknown)
    Internal Server Error

## Response 500 fields (application/json):

  - `error` (string)

  - `details` (any)

