> ## Documentation Index
> Fetch the complete documentation index at: https://docs.infery.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate a 3D model

> POST /v1/3d/generations

Produces a mesh from a text prompt, a reference image, or both, and returns it on the same request.

At least one of `prompt` and `image_url` must be present. A prompt longer than 5000 characters is refused.


## OpenAPI

````yaml openapi.json POST /v1/3d/generations
openapi: 3.0.0
info:
  title: Infery Gateway
  description: >-
    Infery Inference Gateway — OpenAI-compatible API for LLMs, embeddings,
    images, audio, and video
  version: '1.0'
  contact: {}
servers:
  - url: https://api.infery.ai
    description: Production
  - url: http://localhost:3001
    description: Local
security: []
tags: []
paths:
  /v1/3d/generations:
    post:
      tags:
        - 3D
      summary: Generate a 3D model from text or an image
      description: >-
        Produces a mesh file from a text prompt, a reference image, or both, and
        returns it on the same request. At least one of `prompt` and `image_url`
        must be present; a prompt longer than 5000 characters is refused.


        Only FAL-served models of `object_3d` modality are eligible — anything
        else is refused with 400. The deliverable is a single mesh file (usually
        `.glb`) behind a download URL; this endpoint does not render,
        texture-edit or convert an existing mesh.


        BILLED. Credits are reserved up front against the worst-case compute the
        model declares and settled against what it actually used, clamped to the
        reserve — so `credits_used` is never larger than the hold. The API key's
        rate limit, allowed-model list and budget are enforced before the
        provider is called.


        The provider is submitted to and polled inside this request, so the call
        can take minutes. Should the gateway stop waiting, it answers 504 with a
        `job_id` in the error body — the work carries on server-side and is
        still billed, and the result is then collected from `GET
        /v1/images/jobs/{id}`.
      operationId: createObject3d
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateObject3dDto'
      responses:
        '200':
          description: The generated mesh. `data` normally holds a single artifact.
          headers:
            x-request-id:
              schema:
                type: string
              description: Correlation id for this request
            x-model-used:
              schema:
                type: string
              description: >-
                Slug of the model that actually handled the request (differs
                from the requested one when fallback fires)
            x-fallback-from:
              schema:
                type: string
              description: 'Present only when fallback fired: the slug originally requested'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Object3dGenerationResponseDto'
        '400':
          description: >-
            Invalid request — missing `model`, neither `prompt` nor `image_url`,
            an over-long prompt, or a model that is not a FAL 3D model
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '401':
          description: Unauthorized — invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '403':
          description: Quota exceeded (rate limit / model not allowed / budget)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '404':
          description: Model not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '504':
          description: >-
            The gateway stopped waiting. The job continues and is still billed —
            collect it from `GET /v1/images/jobs/{id}` using the `job_id` in the
            error body.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
      security:
        - ApiKey: []
components:
  schemas:
    CreateObject3dDto:
      type: object
      properties:
        model:
          type: string
          description: >-
            Slug of the 3D model to run, as listed by `GET /v1/models`. Must be
            an `object_3d`-modality model served by FAL; anything else is
            rejected with 400.
        prompt:
          type: string
          description: >-
            Text prompt for text-to-3D. Either `prompt` (non-blank) or
            `image_url` must be supplied; both may be. Rejected above 5000
            characters.
          maxLength: 5000
          example: A low-poly wooden chair
        image_url:
          type: string
          description: >-
            Reference image for image-to-3D, as a URL. Forwarded onto the
            model's own image input field when it declares one, and dropped
            otherwise. Either `prompt` or `image_url` must be supplied.
          example: https://example.com/reference.png
        mesh_url:
          type: string
          description: >-
            An existing mesh to transform, as a URL. This is what the 3D-to-3D
            models take — rigging, remesh, retexture, segment. Forwarded onto
            whichever field the model's own schema declares for it (`mesh_url`
            on hi3d and tripo, `model_url` on meshy). A model that transforms a
            mesh REQUIRES this and is refused without it; a model that generates
            one refuses it.
          example: https://storage.googleapis.com/…/chair.glb
        seed:
          type: number
          description: >-
            Seed forwarded onto the model's own seed input field when it
            declares one, and dropped otherwise. Reproducibility therefore
            depends on the model exposing a seed.
      required:
        - model
    Object3dGenerationResponseDto:
      type: object
      properties:
        created:
          type: integer
          description: Unix timestamp, in seconds, of when the result was produced.
          example: 1713204900
        data:
          description: >-
            One entry per produced mesh, in the order the provider returned
            them.
          type: array
          items:
            $ref: '#/components/schemas/Object3dArtifactDto'
        credits_used:
          type: number
          description: >-
            Credits actually settled for this request (1 credit = $0.01).
            Settled against measured compute for per_second models, clamped to
            the amount reserved before the call, so it is never larger than the
            hold. May be fractional.
          example: 25
      required:
        - created
        - data
        - credits_used
    ErrorResponseDto:
      type: object
      properties:
        error:
          description: >-
            The error envelope. Every non-2xx response from this API has this
            shape, so a client can parse failures without branching on the
            endpoint.
          allOf:
            - $ref: '#/components/schemas/ErrorDetailDto'
      required:
        - error
    Object3dArtifactDto:
      type: object
      properties:
        url:
          type: string
          description: >-
            Provider-hosted download URL for the generated mesh. This is the
            upstream (FAL) CDN link and expires in roughly an hour — download or
            copy the bytes promptly rather than storing the URL.
          example: https://example.com/mesh.glb
        content_type:
          type: string
          description: >-
            MIME type the provider reported for the mesh file (the deliverable
            is usually a `.glb`). Present only when the provider supplied one;
            on the synchronous path the same value applies to every entry.
        file_id:
          type: string
          description: >-
            Identifier of the durable `ApiFile` this mesh was registered as,
            usable with `GET /v1/files/{fileId}` and `GET
            /v1/files/{fileId}/content`. Only produced on the media-job path,
            and omitted (never null) for an artifact whose registration failed.
            Registered bytes count towards the workspace storage quota.
          example: file_1hR9xTPZqK4mVLc2nJ7fY5wB
      required:
        - url
    ErrorDetailDto:
      type: object
      properties:
        message:
          type: string
          example: Model not found
          description: Human-readable error message
        type:
          type: string
          example: invalid_request_error
          description: Error category
          enum:
            - invalid_request_error
            - authentication_error
            - permission_error
            - quota_exceeded
            - rate_limit_error
            - server_error
        code:
          type: string
          example: model_not_found
          nullable: true
          description: >-
            Stable machine-readable error code. Branch on this rather than on
            `message`, which is prose and may be reworded.
        param:
          type: string
          example: model
          nullable: true
          description: >-
            Name of the request parameter that triggered the error. `null` when
            the error is not attributable to one field.
        job_id:
          type: string
          example: job_1hR9xTPZqK4mVLc2nJ7fY5wB
          description: >-
            Handle to work that is ALREADY RUNNING AND ALREADY BILLED, present
            on the few errors that carry one. When it is here, this is not a
            failure to retry — retrying pays twice. Collect the result from `GET
            /v1/images/jobs/{job_id}`, which serves every durable media job
            regardless of modality.


            Two situations produce it. A media generation that outruns the
            gateway's wait answers `504` with `code: "job_timeout"` and keeps
            working. And `POST /v1/audio/speech` answers **500** with `code:
            "artifact_unreadable"` when the speech was generated and settled but
            could not be read back from storage — the audio exists and is paid
            for; only this response failed.


            Declared here rather than per-endpoint because the rule is about the
            FIELD, not the status: if this is present, there is a paid-for
            result to collect. It was undeclared until now, so a client
            generated from this document could not see the one field that
            recovers money already spent.
      required:
        - message
        - type
        - code
        - param
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: 'API key in format: Bearer inf_***'

````