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

# Subir imagen

> Sube una imagen para obtener una URL que puede usarse con las APIs de generación de imagen/video

<Note>
  **El Playground de la documentación no admite la subida de archivos**: Por favor, utilice los ejemplos de código cURL, Python o JavaScript que aparecen a continuación para probar.
</Note>

<Warning>
  **Cambio importante:** Para un mejor rendimiento y control de costos, ya no admitimos el envío de datos de imagen en base64 directamente en las APIs de generación. Por favor, utilice esta API para subir las imágenes, obtenga la URL y luego llame a la API de generación.
</Warning>

## ¿Por qué subir las imágenes primero?

1. **Optimización de rendimiento** - La codificación base64 aumenta los datos en un 33%; subir primero reduce considerablemente el tamaño del cuerpo de la solicitud
2. **Reutilización de imágenes** - Suba una vez y reutilice la URL múltiples veces sin transferencias redundantes

## Flujo de trabajo

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant APIMart
    participant Storage

    Client->>APIMart: POST /v1/uploads/images (Upload image file)
    APIMart->>Storage: Save image
    Storage-->>APIMart: Return storage path
    APIMart-->>Client: Return image URL
    Client->>APIMart: POST /v1/images/generations (Use image URL)
```

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/v1/uploads/images \
    --header 'Authorization: Bearer <token>' \
    --form 'file=@/path/to/your/image.jpg'
  ```

  ```python Python theme={null}
  import requests

  # Upload image
  with open('image.jpg', 'rb') as f:
      response = requests.post(
          "https://api.apimart.ai/v1/uploads/images",
          headers={
              "Authorization": "Bearer <token>"
          },
          files={
              "file": f
          }
      )

  result = response.json()
  image_url = result['url']
  print(f"Image URL: {image_url}")

  # Use the uploaded image for generation
  response = requests.post(
      "https://api.apimart.ai/v1/images/generations",
      headers={
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json"
      },
      json={
          "model": "gemini-3-pro-image-preview",
          "prompt": "Create a variation based on this image",
          "image_urls": [{"url": image_url}]
      }
  )
  ```

  ```javascript JavaScript theme={null}
  // Upload image
  const formData = new FormData();
  formData.append('file', fileInput.files[0]);

  const uploadResponse = await fetch('https://api.apimart.ai/v1/uploads/images', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <token>'
    },
    body: formData
  });

  const uploadResult = await uploadResponse.json();
  const imageUrl = uploadResult.url;
  console.log(`Image URL: ${imageUrl}`);

  // Use the uploaded image for generation
  const genResponse = await fetch('https://api.apimart.ai/v1/images/generations', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <token>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'gemini-3-pro-image-preview',
      prompt: 'Create a variation based on this image',
      image_urls: [{url: imageUrl}]
    })
  });
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "url": "https://upload.apimart.ai/f/image/9990000123456-a1b2c3d4-photo.jpg",
    "filename": "photo.jpg",
    "content_type": "image/jpeg",
    "bytes": 235680,
    "created_at": 1743436800
  }
  ```

  ```json 400 - Missing File Field theme={null}
  {
    "error": {
      "message": "missing or invalid file field: http: no such file",
      "type": "invalid_request_error"
    }
  }
  ```

  ```json 400 - Unsupported Format theme={null}
  {
    "error": {
      "message": "unsupported image type: application/pdf, allowed: jpeg, png, gif, webp",
      "type": "invalid_request_error"
    }
  }
  ```

  ```json 413 - File Too Large theme={null}
  {
    "error": {
      "message": "file size 25165824 exceeds maximum 20971520 bytes",
      "type": "invalid_request_error"
    }
  }
  ```

  ```json 429 - Rate Limit Exceeded theme={null}
  {
    "error": {
      "code": 429,
      "message": "Rate limit exceeded. Please try again later",
      "type": "rate_limit_error"
    }
  }
  ```

  ```json 500 - Upload Failed theme={null}
  {
    "error": {
      "message": "failed to upload image",
      "type": "server_error"
    }
  }
  ```
</ResponseExample>

## Autorizaciones

<ParamField header="Authorization" type="string" required>
  Todas las APIs requieren autenticación mediante Bearer Token

  Obtener API Key:

  Visite la [página de gestión de API Keys](https://apimart.ai/keys) para obtener su API Key

  Añádala a los encabezados de la solicitud:

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

## Body

<ParamField body="file" type="file" required>
  Archivo de imagen

  Formatos admitidos: JPEG (.jpg, .jpeg), PNG (.png), WebP (.webp), GIF (.gif)

  Tamaño máximo del archivo: 20MB
</ParamField>

## Respuesta

<ResponseField name="url" type="string">
  URL de acceso público a la imagen; puede utilizarse directamente en las APIs de generación (válida durante 72 horas)
</ResponseField>

<ResponseField name="filename" type="string">
  Nombre original del archivo
</ResponseField>

<ResponseField name="content_type" type="string">
  Tipo MIME detectado, por ejemplo `image/jpeg`
</ResponseField>

<ResponseField name="bytes" type="integer">
  Tamaño del archivo en bytes
</ResponseField>

<ResponseField name="created_at" type="integer">
  Hora de subida como timestamp Unix (segundos)
</ResponseField>

## Ejemplo completo: flujo de imagen a imagen

```python Python theme={null}
import requests
import time

API_KEY = "your-Apimart-key"
BASE_URL = "https://api.apimart.ai"

# Step 1: Upload reference image
def upload_image(file_path):
    with open(file_path, 'rb') as f:
        response = requests.post(
            f"{BASE_URL}/v1/uploads/images",
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"file": f}
        )
    return response.json()['url']

# Step 2: Create generation task
def create_generation(image_url, prompt):
    response = requests.post(
        f"{BASE_URL}/v1/images/generations",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "model": "gemini-3-pro-image-preview",
            "prompt": prompt,
            "image_urls": [{"url": image_url}],
            "size": "16:9"
        }
    )
    return response.json()['id']

# Step 3: Poll task status
def wait_for_result(task_id):
    while True:
        response = requests.get(
            f"{BASE_URL}/v1/images/generations/{task_id}",
            headers={"Authorization": f"Bearer {API_KEY}"}
        )
        result = response.json()

        if result['status'] == 'completed':
            return result['url']
        elif result['status'] == 'failed':
            raise Exception(f"Generation failed: {result.get('fail_reason')}")

        time.sleep(2)

# Execute workflow
image_url = upload_image("reference.jpg")
print(f"Image uploaded: {image_url}")

task_id = create_generation(image_url, "Transform this photo into Ghibli anime style")
print(f"Task created: {task_id}")

result_url = wait_for_result(task_id)
print(f"Generation complete: {result_url}")
```
