The AltTextLab API requires a publicly accessible image URL. Images stored in a private S3 bucket cannot be accessed directly — but you can grant temporary, scoped access using an S3 presigned URL.
A presigned URL embeds your credentials and an expiry time into the URL itself. You generate it server-side, pass it to the API, and it becomes invalid once the signature expires — no permanent exposure, no bucket policy changes required.
How it works
- Your server generates a presigned URL for the S3 object, valid for a short window (30–60 seconds is usually enough).
- You send the presigned URL to the AltTextLab API as
imageUrl.
- The API fetches the image, generates alt text, and returns the result.
- The presigned URL expires automatically.
Your bucket stays private throughout.
Step 1: Generate a presigned URL
Use the AWS SDK for your language to sign a GetObject request. Set the expiry short enough that the URL cannot be reused — 60 seconds works for most cases.
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
const client = new S3Client({ region: 'us-east-1' });
const command = new GetObjectCommand({
Bucket: 'your-private-bucket',
Key: 'path/to/image.jpg',
});
const signedUrl = await getSignedUrl(client, command, { expiresIn: 60 });
Your AWS credentials need s3:GetObject permission on the bucket or key. The credentials used to sign the URL are never exposed — only the signature is embedded in the URL.
Step 2: Pass the presigned URL to the API
Use the signed URL as imageUrl in your generation request. Everything else works the same as with a public URL.
const response = await fetch('https://app.alttextlab.com/api/v1/alt-text/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
body: JSON.stringify({
imageUrl: signedUrl,
lang: 'en',
style: 'neutral',
}),
});
const data = await response.json();
console.log(data.result);
Complete example
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
async function generateAltText(bucket, key) {
const client = new S3Client({ region: 'us-east-1' });
const command = new GetObjectCommand({ Bucket: bucket, Key: key });
const signedUrl = await getSignedUrl(client, command, { expiresIn: 60 });
const response = await fetch('https://app.alttextlab.com/api/v1/alt-text/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.ALTTEXTLAB_API_KEY,
},
body: JSON.stringify({ imageUrl: signedUrl, lang: 'en' }),
});
const data = await response.json();
return data.result;
}
AWS documentation