Developers
Upload, search, and attach media assets
Import images and videos, upload local files, page through the media library, and attach owned asset IDs to social posts.
Updated
Upload first, then attach the returned ID
A media upload creates a library asset. It does not create or publish a post. Use a key with media to upload and read to list. Pass the returned asset id to POST /v1/posts as an entry in asset_ids. Storage is charged to the account, while library listings can be filtered by brand.
Upload a local image as raw bytes
curl --fail-with-body https://api.krevaya.com/v1/assets/upload \
-H "Authorization: Bearer $KREVAYA_API_KEY" \
-H 'Content-Type: image/png' \
--data-binary @./product-photo.pngThis route accepts the file itself, not a multipart form. Images are limited to 15 MB. Direct video uploads are refused on this route; use URL ingest or the chunked video flow.
Import a public image or video URL
# Replace the URL with a publicly reachable file you have permission to use.
curl --fail-with-body https://api.krevaya.com/v1/assets \
-H "Authorization: Bearer $KREVAYA_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"url":"https://example.com/product-photo.png"}'URL ingest supports images up to 15 MB and videos up to 500 MB. The URL must resolve to a public network destination. An authenticated page, local address, or link to an HTML viewer is not a substitute for a downloadable media file. Upload success does not certify that every publishing platform accepts that format, duration, or aspect ratio.
Upload a video in parts
- POST /v1/assets/upload/init with filename and size_bytes. Save upload_id and use the returned part_bytes; do not hard-code the chunk size.
- Split the original file into contiguous chunks of at most part_bytes. PUT each raw chunk to /v1/assets/upload/part?upload_id=…&index=… with zero-based indexes. URL-encode upload_id.
- POST /v1/assets/upload/finish with upload_id and the number of parts. Save the returned asset ID.
# Python 3, standard library. Usage: python upload-video.py ./clip.mp4
import json, math, os, pathlib, sys, urllib.parse, urllib.request
path = pathlib.Path(sys.argv[1])
base = 'https://api.krevaya.com'
key = os.environ['KREVAYA_API_KEY']
def send(method, route, data, content_type='application/json'):
request = urllib.request.Request(base + route, data=data, method=method, headers={
'Authorization': 'Bearer ' + key, 'Content-Type': content_type,
})
with urllib.request.urlopen(request, timeout=180) as response:
return json.load(response)
session = send('POST', '/v1/assets/upload/init', json.dumps({
'filename': path.name, 'size_bytes': path.stat().st_size,
}).encode())
part_bytes = session['part_bytes']
parts = math.ceil(path.stat().st_size / part_bytes)
if parts > 80:
raise SystemExit('This file exceeds the public API part count; use the dashboard.')
with path.open('rb') as source:
for index in range(parts):
query = urllib.parse.urlencode({'upload_id': session['upload_id'], 'index': index})
send('PUT', '/v1/assets/upload/part?' + query, source.read(part_bytes),
'application/octet-stream')
asset = send('POST', '/v1/assets/upload/finish', json.dumps({
'upload_id': session['upload_id'], 'parts': parts,
}).encode())
print(json.dumps(asset))Search and page through your library
curl --fail-with-body --get https://api.krevaya.com/v1/assets \
-H "Authorization: Bearer $KREVAYA_API_KEY" \
--data-urlencode 'kind=image' \
--data-urlencode 'q=iced coffee' \
--data-urlencode 'limit=50' \
--data-urlencode "brand_id=$KREVAYA_BRAND_ID"q searches titles, descriptions, and tags. Every search word must match, with prefix matching; the best matches come first. Send next_cursor back as cursor with the same filters to request the next page. Without limit, the route returns the whole matching library. Use kind=image, video, or audio; audio belongs on a video design's timeline, not in a post's asset_ids.
Delete an asset
DELETE /v1/assets/{asset_id} requires media and returns 204 with no body, or 404 when the asset is not found for your account. Treat deletion as a destructive action in your integration. Keep the original file in your own system when your workflow needs a source archive.
Frequently asked questions
Should I use multipart/form-data for images?
No. POST /v1/assets/upload expects raw image bytes in the request body. Set the image Content-Type and send the file directly.
Can an audio asset be attached to a social post?
Not through asset_ids. Audio assets are tracks for editable video designs; export the finished video before posting it.