Conventions
Behaviour that holds across every endpoint, so the reference does not have to repeat it 101 times.
Requests
All requests are HTTPS. Bodies are JSON with Content-Type: application/json, except file uploads, which are covered below. Paths are case-sensitive. Unknown fields in a request body are rejected rather than ignored, so a typo in a field name surfaces as a 400 instead of silently doing nothing.
Status codes
| 200 | Success. The body carries the resource or result. |
| 201 | Created. Returned by endpoints that create a record. |
| 400 | The request was malformed or failed validation. Fix and resend; retrying unchanged will not help. |
| 401 | Missing, expired or rejected token. Mint a new one; if it persists, assume revoked. |
| 403 | Authenticated but not permitted — usually a record belonging to another organization. |
| 404 | No such route, or no such record visible to your organization. These are deliberately indistinguishable. |
| 429 | Rate limited. Honour Retry-After. |
| 500 | A fault on our side. Safe to retry with backoff; report it with the apigw-requestid. |
403 and 404 deserve a note. Asking for a record that belongs to another organization returns the same response as asking for one that does not exist. That is intentional — the alternative lets a caller map out which record ids are real by watching which error comes back.
Error responses
Errors carry a JSON body. Read the status code first and the message second: messages are written for a human reading a log and may change, while status codes are contractual.
{
"message": "Unauthorized"
}The token endpoint on movik.us uses a richer shape with a stable error code you can branch on — see token endpoint errors.
File uploads
Uploads are a three-step flow rather than a multipart post, because the file goes to S3 directly and never transits the API. This keeps large documents off the request path.
1. Ask for a pre-signed URL with POST /files. You get back a fileKey and an uploadUrl.
2. PUT the raw bytes to that URL. Do not attach your bearer token — the signature in the URL is the authorization, and adding a token makes S3 reject the upload.
3. Confirm with POST /files/confirm so Movik records the upload as complete. A file that is never confirmed is treated as abandoned.
# 1. request a URL
curl -X POST https://api.dev.movik.us/files \
-H "Authorization: Bearer $ID_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"folder":"leads","originalFileName":"carrier.jpg","contentType":"image/jpeg"}'
# 2. upload the bytes — no Authorization header
curl -X PUT "$UPLOAD_URL" \
-H 'Content-Type: image/jpeg' \
--data-binary @carrier.jpg
# 3. confirm
curl -X POST https://api.dev.movik.us/files/confirm \
-H "Authorization: Bearer $ID_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"fileKey":"'"$FILE_KEY"'"}'See the Files reference for exact fields.
Retries and idempotency
GET and DELETE are safe to retry. POST is not idempotent unless an endpoint says so, so a retry after a timeout can create a second record. Where you cannot tolerate a duplicate, retry with a read first: look up whether the record landed, then decide.
Retry 500 and 429 with exponential backoff. Do not retry 400, 403 or 404 — the answer will not change.
Reporting a problem
Every response carries an apigw-requestid header identifying that exact invocation. Include it with the path, the status and the approximate time when you write to support@movik.us. With it we can find your request in the logs directly; without it we are guessing.