Quickstart

Before you begin, make sure you have:

  1. Your Que API Key from the developer dashboard.
  2. A local image file to sign (e.g., my-image.jpg).

1. Configure Your API Key

For security, it's best to set your API key as an environment variable rather than hardcoding it in your application.

export QUE_API_KEY="YOUR_API_KEY"

Our SDKs will automatically detect and use this environment variable.

2. Upload Your Asset

Upload your local file using the SDK. The SDK handles getting presigned URLs and uploading to S3 automatically.

import { Que } from "que-sdk";

const que = new Que({
  apiKeyAuth: process.env["QUE_API_KEY_AUTH"] ?? "",
});

const filePath = "./my-image.jpg";

// Get presigned URL for upload
const presignedResult = await que.getPresignedUrl({
  filename: filePath.split('/').pop() || "my-image.jpg",
});

// Upload file to S3 using the presigned URL
// (You'll need to implement the actual file upload using fetch or your preferred HTTP client)
import { readFileSync } from 'fs';
const fileBuffer = readFileSync(filePath);
const uploadResponse = await fetch(presignedResult.uploadUrl, {
  method: 'PUT',
  body: fileBuffer,
  headers: {
    'Content-Type': 'image/jpeg', // Adjust based on your file type
  },
});

if (!uploadResponse.ok) {
  throw new Error('Failed to upload file');
}

console.log(`Asset uploaded with key: ${presignedResult.key}`);
import os
from que_media import Que

with Que(
    api_key_auth=os.getenv("QUE_API_KEY_AUTH", ""),
) as que:

    file_path = "./my-image.jpg"

    # Get presigned URL for upload
    presigned_result = que.get_presigned_url(filename="my-image.jpg")

    # Upload file to S3 using the presigned URL
    # (You'll need to implement the actual file upload using requests or your preferred HTTP client)
    import requests

    with open(file_path, 'rb') as file:
        upload_response = requests.put(
            presigned_result.upload_url,
            data=file,
            headers={'Content-Type': 'image/jpeg'}
        )

    if upload_response.status_code == 200:
        print(f"Asset uploaded with key: {presigned_result.key}")
    else:
        raise Exception('Failed to upload file')
package main

import (
	"fmt"
	"addque.org/sdk/go"
)

func main() {
	client, err := que.NewClient()
	if err != nil {
		panic(err)
	}
	
	filePath := "./my-image.jpg"
	
	// Upload the file - SDK handles presigned URL and upload automatically
	asset, err := client.Assets.Upload(filePath)
	if err != nil {
		panic(err)
	}
	
	fmt.Printf("Asset uploaded with key: %s\n", asset.Key)
}
use que_sdk::QueClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = QueClient::new();
    let file_path = "./my-image.jpg";

    // Upload the file - SDK handles presigned URL and upload automatically
    let asset = client.assets.upload(file_path).await?;
    println!("Asset uploaded with key: {}", asset.key);
    
    Ok(())
}
package hello.world;

import java.lang.Exception;
import java.io.File;
import java.io.FileInputStream;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import org.openapis.openapi.Que;
import org.openapis.openapi.models.components.*;
import org.openapis.openapi.models.errors.ProblemResponseException;
import org.openapis.openapi.models.operations.GetPresignedUrlResponse;

class Quickstart {

    public static void main(String[] args) throws ProblemResponseException, ProblemResponseException, ProblemResponseException, Exception {

        Que sdk = Que.builder()
                .apiKeyAuth(System.getenv().getOrDefault("API_KEY_AUTH", ""))
            .build();

        String filePath = "./my-image.jpg";

        // Get presigned URL for upload
        GetPresignedUrlRequest presignReq = GetPresignedUrlRequest.builder()
                .filename("my-image.jpg")
                .build();

        GetPresignedUrlResponse presignRes = sdk.getPresignedUrl()
                .request(presignReq)
                .call();

        if (presignRes.presignedUrlResponse().isPresent()) {
            // Upload file to S3 using the presigned URL
            File file = new File(filePath);
            byte[] fileBytes = java.nio.file.Files.readAllBytes(file.toPath());

            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(presignRes.presignedUrlResponse().get().uploadUrl()))
                .header("Content-Type", "image/jpeg")
                .PUT(HttpRequest.BodyPublishers.ofByteArray(fileBytes))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() == 200) {
                System.out.println("Asset uploaded with key: " + presignRes.presignedUrlResponse().get().key());
            } else {
                System.out.println("Upload failed: " + response.statusCode());
            }
        }
    }
}
<?php
declare(strict_types=1);

require 'vendor/autoload.php';

use Que;
use Que\Models\Components;

$sdk = Que\Que::builder()
    ->setSecurity(getenv('QUE_API_KEY_AUTH') ?: '')
    ->build();

$filePath = './my-image.jpg';

// Get presigned URL for upload
$presignedRequest = new Components\GetPresignedUrlRequest(
    filename: basename($filePath)
);

$presignedResponse = $sdk->getPresignedUrl(
    request: $presignedRequest
);

// Upload file to S3 using the presigned URL
$fileContent = file_get_contents($filePath);
$context = stream_context_create([
    'http' => [
        'method' => 'PUT',
        'header' => 'Content-Type: image/jpeg',
        'content' => $fileContent
    ]
]);

$result = file_get_contents($presignedResponse->getPresignedUrlResponse->uploadUrl, false, $context);

if ($result !== false) {
    echo "Asset uploaded with key: " . $presignedResponse->getPresignedUrlResponse->key . "\n";
}
?>

3. Sign the Asset

Now that the file is uploaded, we can sign it with a manifest containing provenance information.

// Sign the asset with a manifest
const signedAsset = await que.signAsset({
  asset: {
    bucket: "your-bucket", // Replace with your actual bucket
    key: presignedResult.key,
  },
  manifestJson: JSON.stringify({
    title: "My First Signed Image",
    assertions: [{
      label: "stds.schema-org.CreativeWork",
      data: {
        "@context": "https://schema.org",
        "@type": "CreativeWork",
        "author": [{ "@type": "Person", "name": "Quickstart User" }]
      }
    }]
  })
});

console.log("Signed asset location:", signedAsset.asset.s3Uri);
# Sign the asset with a manifest
import json

manifest_json = json.dumps({
    "title": "My First Signed Image",
    "assertions": [{
        "label": "stds.schema-org.CreativeWork",
        "data": {
            "@context": "https://schema.org",
            "@type": "CreativeWork",
            "author": [{ "@type": "Person", "name": "Quickstart User" }]
        }
    }]
})

signed_asset = que.sign_asset(
    asset={
        "bucket": "your-bucket",  # Replace with your actual bucket
        "key": presigned_result.key
    },
    manifest_json=manifest_json
)
print("Signed asset location:", signed_asset.asset.s3_uri)
// Sign the asset with a manifest
manifest := que.Manifest{
    Title: "My First Signed Image",
    Assertions: []que.Assertion{
        {
            Label: "stds.schema-org.CreativeWork",
            Data: map[string]interface{}{
                "@context": "https://schema.org",
                "@type":    "CreativeWork",
                "author": []map[string]string{
                    {"@type": "Person", "name": "Quickstart User"},
                },
            },
        },
    },
}

signedAsset, err := client.Assets.Sign(asset.Key, manifest)
if err != nil {
    panic(err)
}

fmt.Println("Signed asset location:", signedAsset.AssetS3URI)
// Sign the asset with a manifest
let manifest = que_sdk::Manifest {
    title: "My First Signed Image".to_string(),
    assertions: vec![que_sdk::Assertion {
        label: "stds.schema-org.CreativeWork".to_string(),
        data: serde_json::json!({
            "@context": "https://schema.org",
            "@type": "CreativeWork",
            "author": [{"@type": "Person", "name": "Quickstart User"}]
        }),
    }],
};

let signed_asset = client.assets.sign(asset.key, manifest).await?;
println!("Signed asset location: {}", signed_asset.asset_s3_uri);
// Sign the asset with a manifest
SignRequest signReq = SignRequest.builder()
        .asset(AssetRefDto.of(S3.builder()
            .bucket("your-bucket") // Replace with your actual bucket
            .key(presignRes.presignedUrlResponse().get().key())
            .build()))
        .manifestJson("{\"title\":\"My First Signed Image\",\"assertions\":[{\"label\":\"stds.schema-org.CreativeWork\",\"data\":{\"@context\":\"https://schema.org\",\"@type\":\"CreativeWork\",\"author\":[{\"@type\":\"Person\",\"name\":\"Quickstart User\"}]}}]}")
        .build();

SignAssetResponse signRes = sdk.signAsset()
        .request(signReq)
        .call();

if (signRes.signResponse().isPresent()) {
    System.out.println("Signed asset location: " + signRes.signResponse().get().asset().s3Uri());
}
<?php
// Sign the asset with a manifest
$signRequest = new Components\SignRequest(
    asset: new Components\S3(
        bucket: 'your-bucket', // Replace with your actual bucket
        key: $presignedResponse->getPresignedUrlResponse->key
    ),
    manifestJson: json_encode([
        'title' => 'My First Signed Image',
        'assertions' => [[
            'label' => 'stds.schema-org.CreativeWork',
            'data' => [
                '@context' => 'https://schema.org',
                '@type' => 'CreativeWork',
                'author' => [['@type' => 'Person', 'name' => 'Quickstart User']]
            ]
        ]]
    ])
);

$response = $sdk->signAsset(
    request: $signRequest
);

if ($response->signResponse !== null) {
    echo "Signed asset location: " . $response->signResponse->asset->s3Uri . "\n";
}
?>

Next Steps

Congratulations! You've successfully attached Content Credentials to a digital asset. The signed file now contains a verifiable history of its origin.

  • Learn more about creating manifests in Manifests.
  • Explore how to check an asset's history in Verification.