Prompt
How do I set up a creative spec validator for checking file format, resolution, and aspect ratio before upload?
Latest observation
A good way to set this up is to treat the “creative spec validator” as a small pre-upload rules engine:
- Define the allowed specs
- Inspect the file before upload
- Compare actual properties to the rules
- Return clear pass/fail messages
Here’s a practical structure.
1) Define your creative requirements
For each upload type, specify:
- Allowed file formats: e.g.
jpg,jpeg,png,gif,mp4 - Minimum or exact resolution: e.g.
1080x1080 - Allowed aspect ratio(s): e.g.
1:1,16:9,9:16 - Optional:
- Max file size
- Duration limits for video
- Color space, bitrate, transparent background rules, etc.
Example spec object:
{
"allowedFormats": ["jpg", "jpeg", "png"],
"minWidth": 1080,
"minHeight": 1080,
"aspectRatio": {
"type": "exact",
"value": 1.0,
"tolerance": 0.01
}
}
2) Validate the file type first
Check the extension and, better yet, the actual MIME type.
In JavaScript (browser)
const allowedFormats = ["image/jpeg", "image/png"];
function validateFormat(file) {
return allowedFormats.includes(file.type);
}
If you want to be stricter, inspect the file signature on the server instead of trusting the extension.
3) Read image resolution before upload
For images in the browser:
function getImageDimensions(file) {
return new Promise((resolve, reject) => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
URL.revokeObjectURL(url);
resolve({ width: img.width, height: img.height });
};
img.onerror = () => {
URL.revokeObjectURL(url);
reject(new Error("Invalid image file"));
};
img.src = url;
});
}
4) Calculate aspect ratio
function calculateAspectRatio(width, height) {
return width / height;
}
Then compare against your target:
function validateAspectRatio(width, height, targetRatio, tolerance = 0.01) {
const actualRatio = width / height;
return Math.abs(actualRatio - targetRatio) <= tolerance;
}
Examples:
1:1→1.016:9→1.777...9:16→0.5625
5) Combine all checks into one validator
async function validateCreativeSpec(file, spec) {
const errors = [];
// Format check
if (!spec.allowedFormats.includes(file.type)) {
errors.push(`Unsupported format: ${file.type}`);
}
// Only image example here
const { width, height } = await getImageDimensions(file);
// Resolution check
if (spec.minWidth && width < spec.minWidth) {
errors.push(`Width too small: ${width}px < ${spec.minWidth}px`);
}
if (spec.minHeight && height < spec.minHeight) {
errors.push(`Height too small: ${height}px < ${spec.minHeight}px`);
}
// Aspect ratio check
if (spec.aspectRatio?.type === "exact") {
const actualRatio = width / height;
const diff = Math.abs(actualRatio - spec.aspectRatio.value);
if (diff > spec.aspectRatio.tolerance) {
errors.push(
`Invalid aspect ratio: got ${actualRatio.toFixed(3)}, expected ${spec.aspectRatio.value}`
);
}
}
return {
valid: errors.length === 0,
errors
};
}
Usage:
const spec = {
allowedFormats: ["image/jpeg", "image/png"],
minWidth: 1080,
minHeight: 1080,
aspectRatio: { type: "exact", value: 1.0, tolerance: 0.01 }
};
const result = await validateCreativeSpec(file, spec);
if (!result.valid) {
console.log(result.errors);
}
6) Show validation errors before upload
In your UI, block upload if invalid and show actionable messages like:
- “Only JPG and PNG are allowed.”
- “Image must be at least 1080x1080.”
- “Aspect ratio must be 1:1.”
That helps users fix files immediately.
7) Do the same validation on the server too
Client-side validation improves UX, but it should not be your only guardrail.
On the server:
- verify MIME/file signature
- inspect image metadata
- enforce resolution/aspect ratio
- reject invalid uploads
This prevents bypassing validation by uploading directly to your backend or storage.
8) If you want a reusable schema approach
You can model specs per placement or ad slot:
const specs = {
instagramFeed: {
allowedFormats: ["image/jpeg", "image/png"],
minWidth: 1080,
minHeight: 1080,
aspectRatio: { type: "range", min: 0.8, max: 1.25 }
},
story: {
allowedFormats: ["image/jpeg", "image/png", "video/mp4"],
minWidth: 1080,
minHeight: 1920,
aspectRatio: { type: "exact", value: 9 / 16, tolerance: 0.01 }
}
};
Then choose a spec based on campaign placement and validate against it.
Recommended implementation pattern
- Frontend: quick checks for immediate feedback
- Backend: authoritative validation
- Config-driven rules: easy to update per placement
- Clear error messages: user-friendly and specific
If you want, I can also give you:
- a React example,
- a Node.js/Express server-side validator, or
- a TypeScript schema-based implementation.
Observation history
Unlock observation history
Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.
How did Obsurfable measure this prompt?
Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.
Which AI systems does Obsurfable collect answers from?
OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.