Basic SDK Usage
A complete guide to the MediaViz API — from creating your account to viewing AI-powered photo curation results.
Initialize SDK Client
The MediaViz API authenticates with OAuth2. Before initializing the SDK, you need an OAuth client ID (and, optionally, a client secret) issued by MediaViz.
Don't have a client ID or secret? Reach out to MediaViz and we'll generate credentials for you.
Store your credentials in an environment file (.env) at the root of your project. The client secret is optional — include it only if MediaViz issued you one.
Create an Environment File
# .env
MEDIAVIZ_CLIENT_ID=YOUR_CLIENT_ID
# Optional — include only if MediaViz issued you a client secret
MEDIAVIZ_CLIENT_SECRET=YOUR_CLIENT_SECRET
# .env
MEDIAVIZ_CLIENT_ID=YOUR_CLIENT_ID
# Optional — include only if MediaViz issued you a client secret
MEDIAVIZ_CLIENT_SECRET=YOUR_CLIENT_SECRET
# .env
MEDIAVIZ_CLIENT_ID=YOUR_CLIENT_ID
# Optional — include only if MediaViz issued you a client secret
MEDIAVIZ_CLIENT_SECRET=YOUR_CLIENT_SECRET
# .env
MEDIAVIZ_CLIENT_ID=YOUR_CLIENT_ID
# Optional — include only if MediaViz issued you a client secret
MEDIAVIZ_CLIENT_SECRET=YOUR_CLIENT_SECRET
# .env
MEDIAVIZ_CLIENT_ID=YOUR_CLIENT_ID
# Optional — include only if MediaViz issued you a client secret
MEDIAVIZ_CLIENT_SECRET=YOUR_CLIENT_SECRET
Now that your OAuth client is configured, you can initialize the SDK.
Initialize the SDK Client
import { MediaViz } from '@mediaviz/sdk';
const mediaviz = new MediaViz({
baseUrl: 'https://api.mediaviz.ai',
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'http://localhost:3000/callback',
});
import { MediaViz, MediaVizConfig } from '@mediaviz/sdk';
const config: MediaVizConfig = {
baseUrl: 'https://api.mediaviz.ai',
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'http://localhost:3000/callback',
};
const mediaviz = new MediaViz(config);
const { MediaViz } = require('@mediaviz/sdk');
const mediaviz = new MediaViz({
baseUrl: 'https://api.mediaviz.ai',
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'http://localhost:3000/callback',
});
from mediaviz_sdk import MediaVizClient
mediaviz = MediaVizClient(
base_url='https://api.mediaviz.ai',
client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
redirect_uri='http://localhost:3000/callback',
)
require_once __DIR__ . '/vendor/autoload.php';
use MediaVizSdk\MediaVizClient;
$mediaviz = new MediaVizClient([
'baseUrl' => 'https://api.mediaviz.ai',
'clientId' => 'YOUR_CLIENT_ID',
'clientSecret' => 'YOUR_CLIENT_SECRET',
'redirectUri' => 'http://localhost:3000/callback',
]);
Once initialized, the SDK handles OAuth for you — it acquires an access token, attaches it to every request, and refreshes it automatically. You never manage tokens directly. If you instead plan to use raw HTTP requests rather than the SDK, refer to the Direct HTTP authentication walkthrough in Full Overview for the full token flow.
Creating Your Account
Create the First Company User
To register a new company and its owner, call users.createUserAndCompany. This creates both the user and the associated company in a single call.
Required fields:
- Name — the user's full name
- Email — a valid email address (used for verification)
- Password — account password
- Company name — the name of your organization
Accounts created this way are automatically assigned the Company Owner role (account_type 3) — there is no account-type parameter to set.
A successful response triggers an email verification message to the provided address and returns the new user's id and company_id (both integers). Record both — you will need them for subsequent requests.
Request Sample
const { id, company_id } = await mediaviz.users.createUserAndCompany(
'Jane Smith',
'jane@example.com',
's3cur3P@ss',
null, // companyId — omit to create a new company
null, // profilePicture — optional avatar URL
null, // paymentPlanType — optional billing plan
'Acme Photography'
);
import type { UserDisplay } from '@mediaviz/sdk';
const { id, company_id }: UserDisplay = await mediaviz.users.createUserAndCompany(
'Jane Smith',
'jane@example.com',
's3cur3P@ss',
null, // companyId — omit to create a new company
null, // profilePicture — optional avatar URL
null, // paymentPlanType — optional billing plan
'Acme Photography'
);
const { id, company_id } = await mediaviz.users.createUserAndCompany(
'Jane Smith',
'jane@example.com',
's3cur3P@ss',
null, // companyId — omit to create a new company
null, // profilePicture — optional avatar URL
null, // paymentPlanType — optional billing plan
'Acme Photography'
);
result = mediaviz.users.create_user_and_company(
'Jane Smith',
'jane@example.com',
's3cur3P@ss',
None, # companyId — omit to create a new company
None, # profilePicture — optional avatar URL
None, # paymentPlanType — optional billing plan
'Acme Photography'
)
# result['id'], result['company_id']
$result = $mediaviz->users->createUserAndCompany(
'Jane Smith',
'jane@example.com',
's3cur3P@ss',
null, // companyId — omit to create a new company
null, // profilePicture — optional avatar URL
null, // paymentPlanType — optional billing plan
'Acme Photography'
);
// $result['id'], $result['company_id']
curl -X POST 'https://api.mediaviz.ai/api/v1/users/new_company/' \
-H 'Content-Type: application/json' \
--data @- <<'JSON'
{
"name": "Jane Smith",
"email": "jane@example.com",
"company_id": null,
"profile_picture": null,
"payment_plan_type": null,
"password": "s3cur3P@ss",
"company_name": "Acme Photography"
}
JSON
Response Sample
{
"id": 8507,
"company_id": 1024,
"name": "Jane Smith",
"email": "jane@example.com",
"account_type": 3
}
To add additional users to an existing company, call POST /api/v1/users/ with a name, email, account_type (1 = standard user, 2 = company admin), and the existing company_id.
Create Collection
A collection is a container for a set of photos that will be processed together by MediaViz AI models. Each collection is identified by a unique project_table_name in the format z-photos-{company_id}-{uuid}.
Collections are scoped to an outcome — the type of analysis you want performed. To create a collection, call project.create_project_and_run specifying the outcomes (e.g., curation) and the models to run. The response returns the project_table_name you will use for all subsequent operations on this collection.
Request Sample
const { project_table_name } = await mediaviz.projects.createProjectAndRun(
'My Wedding Collection',
null, // private — optional; defaults to false
null, // type — optional project type id
'Wedding photos 2026',
null, // directory — optional folder path
2,
null, // thumbnail — optional cover image URL
null, // runName — optional label for this run
{
outcomes: 'curation'
}
);
import type { ProjectRunDisplay } from '@mediaviz/sdk';
const { project_table_name }: ProjectRunDisplay = await mediaviz.projects.createProjectAndRun(
'My Wedding Collection',
null, // private — optional; defaults to false
null, // type — optional project type id
'Wedding photos 2026',
null, // directory — optional folder path
2,
null, // thumbnail — optional cover image URL
null, // runName — optional label for this run
{
outcomes: 'curation'
}
);
const { project_table_name } = await mediaviz.projects.createProjectAndRun(
'My Wedding Collection',
null, // private — optional; defaults to false
null, // type — optional project type id
'Wedding photos 2026',
null, // directory — optional folder path
2,
null, // thumbnail — optional cover image URL
null, // runName — optional label for this run
{
outcomes: 'curation'
}
);
result = mediaviz.projects.create_project_and_run(
'My Wedding Collection',
None, # private — optional; defaults to false
None, # type — optional project type id
'Wedding photos 2026',
None, # directory — optional folder path
2,
None, # thumbnail — optional cover image URL
None, # runName — optional label for this run
outcomes='curation'
)
# result['project_table_name']
$result = $mediaviz->projects->createProjectAndRun(
'My Wedding Collection',
null, // private — optional; defaults to false
null, // type — optional project type id
'Wedding photos 2026',
null, // directory — optional folder path
2,
null, // thumbnail — optional cover image URL
null, // runName — optional label for this run
'curation'
);
// $result['project_table_name']
curl -X POST 'https://api.mediaviz.ai/api/v1/project_outcome/?outcomes=curation' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNyXzAxYWJjMTIzIiwiZXhwIjoxNzQzNjMwMzI5fQ.RwJF-KLLr8K5JgEtIeFiKWELcv-FDLNzMPHJ2St_wAo' \
-H 'Content-Type: application/json' \
--data @- <<'JSON'
{
"name": "My Wedding Collection",
"private": null,
"type": null,
"description": "Wedding photos 2026",
"directory": null,
"photo_upload_vector": 2,
"thumbnail": null,
"run_name": null
}
JSON
Response Sample
{
"project_table_name": "z-photos-1024-a1b2c3d4",
"outcomes": ["curation"],
"models": ["blur", "colors", "face_recognition", "image_classification", "similarity", "evidence"],
"status": "created"
}
Upload Photo
Send each photo to the upload endpoint. You must resize each photo to exactly 256×256 px and Base64-encode it before calling the SDK — the SDK does not resize for you. The SDK handles fetching the upload template for the collection automatically and caches it across calls.
Request Sample
const result = await mediaviz.photoUpload.uploadPhoto(
'z-photos-1024-a1b2c3d4',
1024,
8507,
0,
{
title: 'IMG_0001.jpg',
fileContent: '<base64-encoded image data>',
mimetype: 'image/jpeg',
filePath: '/photos/IMG_0001.jpg'
}
);
const result = await mediaviz.photoUpload.uploadPhoto(
'z-photos-1024-a1b2c3d4',
1024,
8507,
0,
{
title: 'IMG_0001.jpg',
fileContent: '<base64-encoded image data>',
mimetype: 'image/jpeg',
filePath: '/photos/IMG_0001.jpg'
}
);
const result = await mediaviz.photoUpload.uploadPhoto(
'z-photos-1024-a1b2c3d4',
1024,
8507,
0,
{
title: 'IMG_0001.jpg',
fileContent: '<base64-encoded image data>',
mimetype: 'image/jpeg',
filePath: '/photos/IMG_0001.jpg'
}
);
result = mediaviz.photo_upload.upload_photo(
'z-photos-1024-a1b2c3d4',
1024,
8507,
0,
title='IMG_0001.jpg',
file_content='<base64-encoded image data>',
mimetype='image/jpeg',
file_path='/photos/IMG_0001.jpg'
)
$result = $mediaviz->photoUpload->uploadPhoto(
'z-photos-1024-a1b2c3d4',
1024,
8507,
0,
[
'title' => 'IMG_0001.jpg',
'file_content' => '<base64-encoded image data>',
'mimetype' => 'image/jpeg',
'file_path' => '/photos/IMG_0001.jpg'
]
);
# Step 1: get_project_prelim_model_request_template
curl -X GET 'https://api.mediaviz.ai/api/v1/project_outcome/z-photos-1024-a1b2c3d4' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNyXzAxYWJjMTIzIiwiZXhwIjoxNzQzNjMwMzI5fQ.RwJF-KLLr8K5JgEtIeFiKWELcv-FDLNzMPHJ2St_wAo'
# Step 2: Upload a preprocessed photo with metadata via headers
curl -X POST 'https://upload.mediaviz.ai/photo_upload' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNyXzAxYWJjMTIzIiwiZXhwIjoxNzQzNjMwMzI5fQ.RwJF-KLLr8K5JgEtIeFiKWELcv-FDLNzMPHJ2St_wAo' \
-H 'x-company-id: 1024' \
-H 'x-user-id: 8507' \
-H 'x-project-table-name: z-photos-1024-a1b2c3d4' \
-H 'x-title: IMG_0001.jpg' \
-H 'Content-Type: application/json' \
--data @- <<'JSON'
{
"file_content": "<base64-encoded image data>",
"mimetype": "image/jpeg",
"file_path": "/photos/IMG_0001.jpg"
}
JSON
Mark Photo Upload Complete
Once all photos have been uploaded, signal to MediaViz that the upload phase is finished. This triggers the AI processing pipeline to begin.
After this call, the collection transitions to a processing state and the models begin running.
Request Sample
const result = await mediaviz.projects.markProjectUploadComplete('z-photos-1024-a1b2c3d4');
const result = await mediaviz.projects.markProjectUploadComplete('z-photos-1024-a1b2c3d4');
const result = await mediaviz.projects.markProjectUploadComplete('z-photos-1024-a1b2c3d4');
result = mediaviz.projects.mark_project_upload_complete('z-photos-1024-a1b2c3d4')
$result = $mediaviz->projects->markProjectUploadComplete('z-photos-1024-a1b2c3d4');
curl -X POST 'https://api.mediaviz.ai/api/v1/project/z-photos-1024-a1b2c3d4/upload_complete/' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNyXzAxYWJjMTIzIiwiZXhwIjoxNzQzNjMwMzI5fQ.RwJF-KLLr8K5JgEtIeFiKWELcv-FDLNzMPHJ2St_wAo'
Check Run Status
Poll for processing progress. The response includes an overall progress_percentage as well as an individual completion flag for each model that was configured for the collection.
progress_percentage is a fraction between 0 and 1. Each configured model also has its own boolean. Continue polling until progress_percentage reaches 1 and every model flag is true before fetching results.
Request Sample
const result = await mediaviz.projects.checkProjectStatus('z-photos-1024-a1b2c3d4');
const result = await mediaviz.projects.checkProjectStatus('z-photos-1024-a1b2c3d4');
const result = await mediaviz.projects.checkProjectStatus('z-photos-1024-a1b2c3d4');
result = mediaviz.projects.check_project_status('z-photos-1024-a1b2c3d4')
$result = $mediaviz->projects->checkProjectStatus('z-photos-1024-a1b2c3d4');
curl -X GET 'https://api.mediaviz.ai/api/v1/project/status/z-photos-1024-a1b2c3d4' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNyXzAxYWJjMTIzIiwiZXhwIjoxNzQzNjMwMzI5fQ.RwJF-KLLr8K5JgEtIeFiKWELcv-FDLNzMPHJ2St_wAo'
Response Sample
{
"progress_percentage": 0.72,
"blur_model_complete": true,
"colors_model_complete": true,
"face_recognition_model_complete": false,
"image_classification_model_complete": false,
"similarity_model_complete": false,
"evidence_model_complete": false
}
progress_percentage is a decimal between 0 and 1 — a value of 1 means project processing is complete and results are ready to fetch.
Individual Photo Results
Retrieve detailed analysis for a single photo using photo.get_photo_from_project. The response includes the full set of model outputs for that photo, including:
- blur_value — sharpness score
- main_color_palette — dominant colors extracted from the image
- labels_from_classifications_model — image classification tags as a
{ label: confidence }map - bounding_boxes_from_faces_model — detected face regions
- similar_photo_ids_high / _medium / _low — similar photos grouped by similarity strength
- evidence_score — overall curation score
- face_score — quality score for face content
- content_score — subject matter quality score
- aesthetic_score — compositional and aesthetic quality score
- similarity_set_ranking — rank within its similarity cluster
Request Sample
const result = await mediaviz.photos.getPhotoFromProject('z-photos-1024-a1b2c3d4', 1035601);
import type { PhotoDisplay } from '@mediaviz/sdk';
const result: PhotoDisplay = await mediaviz.photos.getPhotoFromProject('z-photos-1024-a1b2c3d4', 1035601);
const result = await mediaviz.photos.getPhotoFromProject('z-photos-1024-a1b2c3d4', 1035601);
result = mediaviz.photos.get_photo_from_project('z-photos-1024-a1b2c3d4', 1035601)
$result = $mediaviz->photos->getPhotoFromProject('z-photos-1024-a1b2c3d4', 1035601);
curl -X GET 'https://api.mediaviz.ai/api/v1/photos/z-photos-1024-a1b2c3d4/1035601' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidXNyXzAxYWJjMTIzIiwiZXhwIjoxNzQzNjMwMzI5fQ.RwJF-KLLr8K5JgEtIeFiKWELcv-FDLNzMPHJ2St_wAo'
Response Sample
{
"id": 1035601,
"blur_value": 0.95,
"main_color_palette": ["#3a5a8c", "#f0e6d2", "#2c2c2c"],
"labels_from_classifications_model": {
"outdoor": 0.98,
"portrait": 0.95,
"natural light": 0.89
},
"bounding_boxes_from_faces_model": [
{ "x": 120, "y": 45, "width": 80, "height": 90 }
],
"similar_photo_ids_high": [1035607],
"similar_photo_ids_medium": [1035612, 1035619],
"similar_photo_ids_low": [1035631],
"evidence_score": 0.91,
"face_score": 0.88,
"content_score": 0.84,
"aesthetic_score": 0.79,
"similarity_set_ranking": 1
}