Skip to main content

Storing Assets

When you store an asset, the asset and its metadata are stored in your object store and database, respectively. There are three ways to store an asset:

  1. Multipart Upload: Use this when the asset content is available locally.
  2. URL Source: Use this when the asset content must be downloaded by Konifer from an external URL.
  3. Amazon S3 ARN Source: Use this when the asset is already stored in Amazon S3.

The request path for all three methods is:

POST /assets/{your/defined/path}

The difference is how the content is supplied. Only one method is allowed per request.

Multipart Upload​

A multipart upload lets you specify the asset content and metadata in the same request.

Do not include source.http.url, source.s3.arn, or the deprecated top-level url field when supplying multipart content.

Part NameContent-TypePurposeRequired?
metadataapplication/jsonA JSON body containing custom, user-defined data about the assetYes (but may be empty{})
assetImage MIME type (e.g., image/jpeg)The raw binary content of the file being stored.Yes

Metadata JSON structure​

The structure for the metadata part is (no fields are required):

{
"alt": "The alt text for an image",
"labels": {
"label-key": "label-value",
"phone": "Android"
},
"tags": [
"cold",
"verified"
]
}
Field NameTypeDescriptionRequired
altStringThe supplied alt text of your assetNo
labelsObjectSupplied key-value pairs associated with the assetNo
tagsArraySupplied attributes associated with the assetNo

URL Source​

Instead of supplying the file contents directly, you can specify a URL that Konifer downloads the asset content from. The request is identical to the multipart metadata, but you must add source.http.url to the request:

{
"source": {
"http": {
"url": "https://yoururl.com/image.jpeg"
}
},
"alt": "The alt text for an image",
"labels": {
"label-key": "label-value",
"phone": "Android"
},
"tags": [
"cold",
"verified"
]
}
Field NameTypeDescriptionRequired
altStringThe supplied alt text of your assetNo
labelsObjectSupplied key-value pairs associated with the assetNo
tagsArraySupplied attributes associated with the assetNo
source.http.urlStringURL source of content. Domain must be allowed within allowed-domains configurationYes

Since there is only JSON in the request, the Content-Type is application/json.

The top-level url field is deprecated. Konifer continues to use it as a fallback when source.http.url is absent.

Amazon S3 ARN Source​

To import an object from Amazon S3, send an application/json request with a conventional S3 object ARN in source.s3.arn:

{
"source": {
"s3": {
"arn": "arn:aws:s3:::asset-imports/customers/123/profile.jpeg"
}
},
"alt": "The alt text for an image",
"labels": {
"label-key": "label-value",
"phone": "Android"
},
"tags": [
"cold",
"verified"
]
}
Field NameTypeDescriptionRequired
altStringThe supplied alt text of your assetNo
labelsObjectSupplied key-value pairs associated with the assetNo
tagsArraySupplied attributes associated with the assetNo
source.s3.arnStringAmazon S3 object ARN in the form arn:partition:s3:::bucket/keyYes

The ARN must contain a bucket and a non-empty object key. S3 access point ARNs and ARNs containing an account or region are not accepted.

Konifer looks for the presence of AWS S3 credentials using the default provider chain. If credentials exist, then S3 ARN uploads are enabled. Configuration under object-store.s3 controls the destination object store and does not configure this source client, so ARN sources also work when the configured object store is a filesystem or S3-compatible service.

Both URL and ARN downloads are limited by source.url.max-bytes. See the Source configuration reference.

Store Asset Response​

Regardless of the upload method used, a successful storage request returns a 201 Created status and the following JSON response containing the asset's information.

HTTP/1.1 201 CREATED
Content-Type: application/json

{
"class": "image",
"alt": "The alt text for an image",
"entryId": 42,
"labels": {
"label-key": "label-value",
"phone": "Android"
},
"tags": [ "cold", "verified" ],
"source": "url",
"sourceUrl": "https://yoururl.com/image.jpeg",
"variants": [
{
"isOriginalVariant": true,
"storeBucket": "assets",
"storeKey": "d905170f-defd-47e4-b606-d01993ba7b42",
"attributes": {
"height": 100,
"width": 200,
"format": "jpg",
"colorSpace": "srgb"
},
"lqip": {
"blurhash": "BASE64",
"thumbhash": "BASE64"
}
}
],
"createdAt": "2025-11-12T01:20:55"
}

Additionally, a Location header is returned containing an absolute, entry-specific asset URL. Konifer uses http.public-url as its base when configured and otherwise uses the incoming request's scheme, host, and port.

Note: The entryId query selector is supplied, so the URL identifies this asset within the path and can be used for later GET and PUT operations.

Field NameTypeDescription
classStringThe type of the asset, currently always image
altStringThe supplied alt text of your asset
entryIdLongSystem-generated unique identifier of asset within path
labelsObjectSupplied key-value pairs associated with the asset
tagsArraySupplied attributes associated with the asset
sourceStringupload, url, or arn, according to how the asset content was supplied
sourceUrlStringSupplied URL or ARN for an external source; absent for multipart content
variantsAssetVariantWill only contain the original variant - the one supplied
createdAtISO 8601Date asset was stored
modifiedAtISO 8601Date asset was last modified (ignores variant generation)

For compatibility, the response field containing the external source is named sourceUrl even when its value is an S3 object ARN. For example, an ARN import returns "source": "arn" and the supplied ARN in sourceUrl.

AssetVariant​

Field NameTypeDescription
isOriginalVariantBooleanWhether the variant is the original variant. For store-asset response, this is true.
storeBucketStringThe S3 bucket the asset is stored in - defined in path configuration
storeKeyStringThe key of the asset in the object store
attributesAttributesExtracted attributes of the asset
transformationTransformationNormalized original variant transformation - not returned for original variants
lqipLQIPLow-Quality Image Placeholder (LQIP) values if enabled in path configuration

Attributes​

Field NameTypeDescription
heightIntegerHeight of variant
widthIntegerWidth of variant
formatFormatFormat of variant
pageCountIntegerNumber of pages in image (1 unless image is animated)
loopIntegerFor multi-paged images, specifies the amount of animated repetitions. Defaults to 0; -1 is continuous looping
colorSpaceStringsrgb, p3, adobe_rgb, cymk, grayscale, the Description tag of the embedded ICC profile, or unknown if unable to determine color space

Format​

FormatNameFile ExtensionContent Type
pngPNG.pngimage/png
jpgJPEG.jpegimage/jpeg
webpWEBP.webpimage/webp
avifAVIF.avifimage/avif
jxlJPEG XL.jxlimage/jxl
heicHEIC.heicimage/heic
gifGIF.gifimage/gif