Genace

AI generation API input validation: reject bad requests before submission

Local validation gives your users a useful error before you send a generation request. Keep it model-specific: duration belongs to a video contract, while image count belongs to an image contract. The gateway validates parameters through the selected provider schema, so a single permissive form for every model can create requests that look reasonable but fail at submission.

1. Separate application rules from API constraints

The current Seedance Fast schema accepts an integer duration from three through fifteen seconds, 720p or 1080p resolution, and five aspect ratios. Nano Banana accepts an integer image count from one through four and the same five aspect ratios. These are adapter constraints in this repository, not a universal rule for every provider.

The following helper creates one narrow Seedance payload. It trims prompts, adds an application-specific length cap, rejects unknown fields, and validates reference URLs under a stricter HTTPS policy than the gateway’s general URL syntax check.

export function validateSeedanceInput(input) {
  if (!input || typeof input !== 'object' || Array.isArray(input)) {
    throw new Error('Expected a JSON object');
  }
  const allowed = new Set(['prompt', 'duration_sec', 'resolution',
    'aspect_ratio', 'image_inputs']);
  if (Object.keys(input).some((name) => !allowed.has(name))) {
    throw new Error('Unexpected request field');
  }
  const prompt = typeof input.prompt === 'string' ? input.prompt.trim() : '';
  if (!prompt || prompt.length > 2000) throw new Error('Invalid prompt');
  const duration = input.duration_sec ?? 5;
  if (!Number.isInteger(duration) || duration < 3 || duration > 15) {
    throw new Error('Duration must be an integer from 3 to 15');
  }
  const resolution = input.resolution ?? '720p';
  if (!['720p', '1080p'].includes(resolution)) throw new Error('Invalid resolution');
  const aspect = input.aspect_ratio ?? '16:9';
  if (!['16:9', '9:16', '1:1', '4:3', '3:4'].includes(aspect)) {
    throw new Error('Invalid aspect ratio');
  }
  const images = input.image_inputs ?? [];
  if (!Array.isArray(images) || images.length > 1) {
    throw new Error('This application accepts one reference image');
  }
  for (const value of images) {
    if (typeof value !== 'string') throw new Error('Invalid image URL');
    const url = new URL(value);
    if (url.protocol !== 'https:' || url.username || url.password) {
      throw new Error('Use an HTTPS image URL without embedded credentials');
    }
  }
  return { model: 'seedance-2.0-fast', prompt, duration_sec: duration,
    resolution, aspect_ratio: aspect, image_inputs: images };
}

2. Preserve model boundaries

Do not reuse this helper unchanged for Nano Banana or Veo. A model switch should select a different validator and reset incompatible form fields. String values such as "5" should either be deliberately converted in your form layer or rejected; silently relying on upstream coercion makes the contract harder to reason about.

The one-reference-image limit above is an application choice reflecting the current Seedance adapter’s use of the first input image. The gateway schema itself accepts an optional URL array. Rejecting extra images locally is clearer than allowing users to believe several references influence the output.

3. Still handle upstream validation errors

Local checks cannot replace the gateway’s validation. Deployments and model adapters can change, and callers can bypass your UI. If the API returns INVALID_PARAM, preserve error.param when available and map the message to the relevant form field. An invalid request should lead to correction rather than automatic identical retries.

Avoid accepting arbitrary extra from public clients. The adapter spreads that object into its upstream input after mapped fields, so it can override behavior beyond your visible form controls. Expose reviewed options explicitly and keep the remaining request body server-controlled.

Common mistakes and verification

Do not label the example’s prompt length cap or HTTPS restriction as a guaranteed Genace limit. They are deliberate local policies. URL parsing also cannot prove that an upstream provider can download the image; accessibility must be checked separately.

Verify empty objects, whitespace prompts, numeric strings, unsupported ratios, oversized arrays, and unknown fields are rejected before fetch. Verify valid boundary durations pass. Finally, exercise a mocked upstream validation error so your application still provides a useful response when its local schema falls behind.

Continue with reference image handling, Seedance parameters, and Nano Banana parameters when expanding supported operations.

Continue with code and integration

Models covered on this page

Where these facts come from

  • Editorial keyword hypothesis; search volume not measured
  • codebase: src/ai/providers/seedance.ts
  • codebase: src/ai/providers/nano-banana.ts
  • codebase: src/ai/jobs/service.ts
  • codebase: src/app/api/v1/video/generations/route.ts