# Import ideas

> Import ideas: POST /v1/ideas/import. Adds several ideas at once (up to 500 per call), as the dashboard does with the ideas it kept in the browser. An item whose id was already imported is skipped (skippedCount), so repeating the call never creates duplicates. Items without a valid title are skipped.

Source: https://praeko.app/docs/en/api/ideas/import-ideas

`POST /v1/ideas/import` · minimum scope: write

Adds several ideas at once (up to 500 per call), as the dashboard does with the ideas it kept in the browser. An item whose `id` was already imported is skipped (`skippedCount`), so repeating the call never creates duplicates. Items without a valid `title` are skipped.

> **Headers** `Authorization: Bearer praeko_…` and `X-Praeko-Contract: en`. Always send both.

## Parameters

| Name | In | Description |
|---|---|---|
| `Idempotency-Key` | header | Idempotency key (1 to 255 visible characters, for example a UUID). Repeating the SAME request with the same key within 24 h returns the stored response (with `Idempotent-Replayed: true`) without running it again; a different request with the same key returns 422 `idempotency_key_reuse`; a request still in progress returns 409 `idempotency_in_progress`. 5xx errors are not stored. The key is scoped per workspace and per route. See [Retry a request safely](https://praeko.app/docs/en/guides/idempotency). |

## Request body

JSON. Required fields must be sent; the others can be left out.

| Field | Type | Description |
|---|---|---|
| `ideas` (required) | object[] | Ideas to import (up to 500 per call). Up to 500 items. |
| `ideas[].id` (optional) | string | Source id (up to 64 characters). An id that was already imported is skipped, which makes the call repeatable. |
| `ideas[].title` (required) | string | Title (1 to 200 characters; longer text is truncated). Without a valid title the item is skipped. |
| `ideas[].note` (optional) | string | Notes (up to 5000 characters; longer text is truncated). |
| `ideas[].group` (optional) | string | Board column; an unknown value becomes `idea`. Values: idea, scripting, ready, posted; default: idea. |
| `ideas[].tags` (optional) | string[] | Tags (up to 20, 40 characters each; the excess is truncated). |
| `ideas[].createdAt` (optional) | string | Original creation date (ISO 8601). Used only if it is valid and not in the future; otherwise, now. |

**Body example**

```json
{
  "ideas": [
    {
      "id": "local-1",
      "title": "How the dashboard stores ideas",
      "group": "idea",
      "tags": [
        "dashboard"
      ],
      "createdAt": "2026-10-28T14:00:00Z"
    },
    {
      "id": "local-2",
      "title": "Script: 364 thousand requests for 42 heroes",
      "note": "Show the log chart.",
      "group": "ready",
      "tags": [
        "behind-the-scenes"
      ]
    }
  ]
}
```

## Example

**curl**

```bash
curl -X POST "https://praeko.app/v1/ideas/import" \
  -H "Authorization: Bearer $PRAEKO_KEY" \
  -H "X-Praeko-Contract: en" \
  -H "Content-Type: application/json" \
  -d '{
  "ideas": [
    {
      "id": "local-1",
      "title": "How the dashboard stores ideas",
      "group": "idea",
      "tags": [
        "dashboard"
      ],
      "createdAt": "2026-10-28T14:00:00Z"
    },
    {
      "id": "local-2",
      "title": "Script: 364 thousand requests for 42 heroes",
      "note": "Show the log chart.",
      "group": "ready",
      "tags": [
        "behind-the-scenes"
      ]
    }
  ]
}'
```

**JavaScript**

```js
const res = await fetch("https://praeko.app/v1/ideas/import", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.PRAEKO_KEY}`,
    "X-Praeko-Contract": "en",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "ideas": [
      {
        "id": "local-1",
        "title": "How the dashboard stores ideas",
        "group": "idea",
        "tags": [
          "dashboard"
        ],
        "createdAt": "2026-10-28T14:00:00Z"
      },
      {
        "id": "local-2",
        "title": "Script: 364 thousand requests for 42 heroes",
        "note": "Show the log chart.",
        "group": "ready",
        "tags": [
          "behind-the-scenes"
        ]
      }
    ]
  }),
});
console.log(res.status, await res.json());
```

**Node**

```js
import { Praeko } from "@praeko/sdk";

const praeko = new Praeko({ url: "https://praeko.app", key: process.env.PRAEKO_KEY });
const resultado = await praeko.ideas.import([
  {
    "id": "local-1",
    "title": "How the dashboard stores ideas",
    "group": "idea",
    "tags": [
      "dashboard"
    ],
    "createdAt": "2026-10-28T14:00:00Z"
  },
  {
    "id": "local-2",
    "title": "Script: 364 thousand requests for 42 heroes",
    "note": "Show the log chart.",
    "group": "ready",
    "tags": [
      "behind-the-scenes"
    ]
  }
]);
console.log(resultado);
```

**Python**

```python
import os
import requests

resp = requests.post(
    "https://praeko.app/v1/ideas/import",
    headers={
        "Authorization": f"Bearer {os.environ['PRAEKO_KEY']}",
        "X-Praeko-Contract": "en",
    },
    json={
        "ideas": [
            {
                "id": "local-1",
                "title": "How the dashboard stores ideas",
                "group": "idea",
                "tags": [
                    "dashboard",
                ],
                "createdAt": "2026-10-28T14:00:00Z",
            },
            {
                "id": "local-2",
                "title": "Script: 364 thousand requests for 42 heroes",
                "note": "Show the log chart.",
                "group": "ready",
                "tags": [
                    "behind-the-scenes",
                ],
            },
        ],
    },
)
print(resp.status_code, resp.json())
```

**PHP**

```php
<?php
$corpo = <<<'JSON'
{
  "ideas": [
    {
      "id": "local-1",
      "title": "How the dashboard stores ideas",
      "group": "idea",
      "tags": [
        "dashboard"
      ],
      "createdAt": "2026-10-28T14:00:00Z"
    },
    {
      "id": "local-2",
      "title": "Script: 364 thousand requests for 42 heroes",
      "note": "Show the log chart.",
      "group": "ready",
      "tags": [
        "behind-the-scenes"
      ]
    }
  ]
}
JSON;

$ch = curl_init('https://praeko.app/v1/ideas/import');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("PRAEKO_KEY"),
        'X-Praeko-Contract: en',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => $corpo,
]);
$resposta = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $resposta, PHP_EOL;
curl_close($ch);
```

**Go**

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
  "ideas": [
    {
      "id": "local-1",
      "title": "How the dashboard stores ideas",
      "group": "idea",
      "tags": [
        "dashboard"
      ],
      "createdAt": "2026-10-28T14:00:00Z"
    },
    {
      "id": "local-2",
      "title": "Script: 364 thousand requests for 42 heroes",
      "note": "Show the log chart.",
      "group": "ready",
      "tags": [
        "behind-the-scenes"
      ]
    }
  ]
}`)
	req, err := http.NewRequest("POST", "https://praeko.app/v1/ideas/import", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("PRAEKO_KEY"))
	req.Header.Set("X-Praeko-Contract", "en")
	req.Header.Set("Content-Type", "application/json")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	out, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.Status, string(out))
}
```

**Ruby**

```ruby
require "net/http"
require "uri"

uri = URI("https://praeko.app/v1/ideas/import")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV['PRAEKO_KEY']}"
request["X-Praeko-Contract"] = "en"
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
  {
    "ideas": [
      {
        "id": "local-1",
        "title": "How the dashboard stores ideas",
        "group": "idea",
        "tags": [
          "dashboard"
        ],
        "createdAt": "2026-10-28T14:00:00Z"
      },
      {
        "id": "local-2",
        "title": "Script: 364 thousand requests for 42 heroes",
        "note": "Show the log chart.",
        "group": "ready",
        "tags": [
          "behind-the-scenes"
        ]
      }
    ]
  }
JSON

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }
puts response.code, response.body
```

**C#**

```csharp
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://praeko.app/v1/ideas/import");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("PRAEKO_KEY"));
request.Headers.Add("X-Praeko-Contract", "en");
request.Content = new StringContent("""
    {
      "ideas": [
        {
          "id": "local-1",
          "title": "How the dashboard stores ideas",
          "group": "idea",
          "tags": [
            "dashboard"
          ],
          "createdAt": "2026-10-28T14:00:00Z"
        },
        {
          "id": "local-2",
          "title": "Script: 364 thousand requests for 42 heroes",
          "note": "Show the log chart.",
          "group": "ready",
          "tags": [
            "behind-the-scenes"
          ]
        }
      ]
    }
""", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");
```

**Java**

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "ideas": [
                {
                  "id": "local-1",
                  "title": "How the dashboard stores ideas",
                  "group": "idea",
                  "tags": [
                    "dashboard"
                  ],
                  "createdAt": "2026-10-28T14:00:00Z"
                },
                {
                  "id": "local-2",
                  "title": "Script: 364 thousand requests for 42 heroes",
                  "note": "Show the log chart.",
                  "group": "ready",
                  "tags": [
                    "behind-the-scenes"
                  ]
                }
              ]
            }
            """;
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://praeko.app/v1/ideas/import"))
            .header("Authorization", "Bearer " + System.getenv("PRAEKO_KEY"))
            .header("X-Praeko-Contract", "en")
            .header("Content-Type", "application/json")
            .method("POST", HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode() + " " + response.body());
    }
}
```

**HTTPie**

```bash
http POST "https://praeko.app/v1/ideas/import" \
  "Authorization: Bearer $PRAEKO_KEY" \
  "X-Praeko-Contract: en" \
  "Content-Type: application/json" \
  --raw='{
  "ideas": [
    {
      "id": "local-1",
      "title": "How the dashboard stores ideas",
      "group": "idea",
      "tags": [
        "dashboard"
      ],
      "createdAt": "2026-10-28T14:00:00Z"
    },
    {
      "id": "local-2",
      "title": "Script: 364 thousand requests for 42 heroes",
      "note": "Show the log chart.",
      "group": "ready",
      "tags": [
        "behind-the-scenes"
      ]
    }
  ]
}'
```

> Official SDK for Node: Install it with `npm install @praeko/sdk` (see [SDK and CLI](https://praeko.app/docs/en/sdk)).

## Response

| Success status | When |
|---|---|
| `200` | Success. |

**Response 200**

```json
{
  "imported": 2,
  "skippedCount": 0
}
```

## Errors

| Status | code | When |
|---|---|---|
| 400 | `empty_body` | The request body is empty. |
| 400 | `invalid_json` | The request body is not a JSON object. |
| 413 | `body_too_large` | The request body is larger than 1 MB. |
| 422 | `invalid_field` | `ideas` is not a list or has more than 500 items. |
| 409 | `idea_limit_reached` | It would exceed 2000 ideas in this workspace. |
| 422 | `idempotency_key_reuse` | The `Idempotency-Key` was already used with a different request (different method, path, query or body). |
| 409 | `idempotency_in_progress` | A request with the same `Idempotency-Key` is still in progress (retry in a moment). |
| 409 | `idempotency_response_too_large` | The original response was larger than 256 KB and was not stored; fetch the resource with GET instead. |

### Errors on any route

| Status | code | When |
|---|---|---|
| 401 | `unauthorized` | The `Authorization: Bearer …` header is missing. |
| 401 | `invalid_api_key` | The key does not exist. |
| 401 | `revoked_api_key` | The key has been revoked. |
| 401 | `expired_api_key` | The key has expired. |
| 403 | `forbidden` | The key's scope is not enough for this route (see the scope badge). |
| 429 | `rate_limited` | The per-minute request limit was exceeded. |

The body of every error is `{ "error": { "code", "message", "details"? } }`. See [all error codes](https://praeko.app/docs/en/guides/errors-and-limits).

## Try it

> **Try it**: the live test needs you to be signed in. It is switched off here.
