> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.taktoria.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.taktoria.com/_mcp/server.

# Duplicate Event

POST https://api.taktoria.com/api/v1/dory/events/{eventId}/duplicate
Content-Type: application/json

A copy of the event, to run it again, Not started until it is given
a start. Its description, passcode, audience and domains, room and
presenter settings, instructions, meeting link (`meetingUrl`, so a
recurring call keeps its link), time zone, hosts and polls (as
drafts) come along; its questions, participants, results, billing
and dates do not. It gets a new code and belongs to whoever made it.
Needs `events:write`.

Reference: https://docs.taktoria.com/api-reference/dory/duplicate-event

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Servers

- `https://api.taktoria.com/api/v1` (Production, default)
- `http://localhost:3000/api/v1` (Local)

## Request

### Path parameters

- `eventId` (string, required)

### Body (application/json)

This endpoint expects an object.

- `title` (string, optional) — The copy's title. Left out, "Copy of" the original's.

## Response

### 200

- `id` (string, required)
- `organizationId` (string, required)
- `title` (string, required)
- `code` (string, required) — The short code the room types. Unique inside the workspace rather than globally, so two workspaces can each hold the memorable one their host wants.
- `status` (enum, required) — Returned as the doors have it (see `EventPhase`): DRAFT for an event waiting for a host, LIVE for one scheduled or open, ENDED for one that is over, even in the few minutes before it is marked so and its overage settled. The times open and close an event by themselves, so a host sets a status only to start one with no time to open at (LIVE), to end one early (ENDED), or to reopen one (LIVE). Reopening an event whose last window has closed clears its `endsAt` and `questionsCloseAt`; setting ENDED settles the overage.
  - Allowed values: `DRAFT`, `LIVE`, `ENDED`
- `phase` (enum, required) — Where the event stands right now, from its times first: it opens at the earlier of `startsAt` and `questionsOpenAt`, and ends at the later of `endsAt` and `questionsCloseAt`, with nobody having to start it.
  - Allowed values: `draft`, `scheduled`, `live`, `ended`
- `audience` (enum, required) — Who may join. Separate from `settings`, which describes how the room behaves once somebody is in it rather than whether they get in.
  - Allowed values: `PUBLIC`, `AUTHENTICATED`, `WORKSPACE`, `DOMAIN`
- `allowedDomains` (list of string, required) — The email domains a `DOMAIN` event chose from the workspace's allow-list, such as `acme.com`. Only those still on it count; empty means the whole allow-list (see `/partner-domains`).
- `requireGoogle` (boolean, required) — For a `DOMAIN` event: an address counts only when proved by signing in with Google, never by an emailed code. The rule as it applies: true whenever the workspace requires Google sign-in, whatever was set on the event.
- `hasPasscode` (boolean, required) — Whether attendees must type a passcode as well as the code. The passcode itself is never returned; set it with `passcode`.
- `settings` (EventSettings, required)
- `createdAt` (datetime, required)
- `updatedAt` (datetime, required)
- `description` (string, optional)
- `startsAt` (datetime, optional) — When the event starts: it opens by itself then (or at `questionsOpenAt`, if that is earlier), and is `scheduled` until it does. With neither, it waits for a host to start it.
- `endsAt` (datetime, optional) — When the event ends, unless `questionsCloseAt` is later: from the later of the two it is `ended`, and within five minutes it is marked ENDED and its overage settled, as ending it by hand does.
- `questionsOpenAt` (datetime, optional) — When questions may be asked, if that is not simply "while live".
- `questionsCloseAt` (datetime, optional) — When questions stop. If it is after `endsAt`, the event stays open until then; before it, the event runs on to its end with no new questions.
- `timeZone` (string, optional) — IANA zone the event's times are written in and shown in, such as `Europe/Berlin`. Absent for none, where the app shows the times in the workspace's default zone, else UTC. The times themselves are absolute either way.
- `instructions` (string, optional)
- `meetingUrl` (string, optional) — The Zoom, Google Meet or Microsoft Teams call the event runs beside, as its join link. Shown to hosts and to the attendees the event lets in; Dory's app inside that meeting opens this event.
- `capacityAtEvent` (integer, optional) — What the workspace was paying for per event when this one was settled. Absent until then: it is copied onto the event so that raising the plan later cannot rewrite an invoice already sent.
- `overageParticipants` (integer, optional)
- `questionCount` (integer, optional)
- `participantCount` (integer, optional)
- `host` (User, optional) — A person in a Taktoria organization.
- `archivedAt` (datetime, optional)

## Errors

### 403 Forbidden Error

Refused, and `error.code` says why. On an app's write endpoints, a signed-in session is refused `viewer_only` when the person is a Viewer of the app (they read it, and change nothing in it), and `seat_required` without a seat on it; a key is never either. Beyond those: `admin_required` when the change is an admin's (an app admin's for an app's admin powers, a workspace admin's for the workspace's settings), `forbidden` when the person may not change this one thing, `read_only_session` for a change only a key makes, `person_required` for what only a signed-in person does through their own account elsewhere (exporting a LaunchCal artifact to their docs tool), which a key cannot, `insufficient_scope` for a key without the scope, and `google_sign_in_required` for a session the workspace's Google rule turns away. Nothing was done.

- `error` (ErrorDetail, required)

### 404 Not Found Error

- `error` (ErrorDetail, required)

### 422 Validation Error

- `error` (ErrorDetail, required)

### 429 Too Many Requests Error

Rate limited (`rate_limited`): the key, the signed-in person, the workspace or an expensive endpoint's own budget is used up for now. `Retry-After` says how many seconds to wait, and `details` names the `policy`, its `limit`, `windowSeconds` and `retryAfter`. Every answer to an authenticated request carries the IETF `RateLimit-Policy` and `RateLimit` headers, so a client can slow down before it gets this. Nothing was done; wait and send it again. See "Rate limits".

- `error` (ErrorDetail, required)

## Types

### EventSettings

- `allowAnonymous` (boolean, required)
- `moderationEnabled` (boolean, required) — New questions arrive PENDING and wait for a host.
- `allowUpvotes` (boolean, required)
- `allowReplies` (boolean, required)
- `profanityFilter` (boolean, required)
- `showPoweredBy` (boolean, required) — Whether "Powered by taktoria.com" shows on the event's way in.
- `presenterControls` (boolean, required) — Whether the presenter screen can spotlight a question, mark it answered and move on.
- `presentShowTiming` (boolean, required) — Whether the presenter screen shows when the event starts and ends.
- `presentBackground` (string, required) — Presenter screen background, `#rrggbb`.
- `presentAccent` (string, required) — Presenter screen accent, `#rrggbb`.
- `presentSubtitle` (string, optional) — A line under the title on the presenter screen.

### User

A person in a Taktoria organization.

- `id` (string, required)
- `name` (string, required)
- `email` (string, required)
- `image` (string, optional) — Their picture: one uploaded on the account page, or else their Google profile picture, brought in when they sign in with Google.

### ErrorDetail

- `code` (string, required) — A stable machine-readable code such as `not_found`.
- `message` (string, required)
- `details` (any, optional)

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "id": "id",
  "organizationId": "organizationId",
  "title": "title",
  "code": "code",
  "status": "DRAFT",
  "phase": "draft",
  "audience": "PUBLIC",
  "allowedDomains": [
    "allowedDomains",
    "allowedDomains"
  ],
  "requireGoogle": true,
  "hasPasscode": true,
  "settings": {
    "allowAnonymous": true,
    "moderationEnabled": true,
    "allowUpvotes": true,
    "allowReplies": true,
    "profanityFilter": true,
    "showPoweredBy": true,
    "presenterControls": true,
    "presentShowTiming": true,
    "presentBackground": "presentBackground",
    "presentAccent": "presentAccent",
    "presentSubtitle": "presentSubtitle"
  },
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z",
  "description": "description",
  "startsAt": "2024-01-15T09:30:00Z",
  "endsAt": "2024-01-15T09:30:00Z",
  "questionsOpenAt": "2024-01-15T09:30:00Z",
  "questionsCloseAt": "2024-01-15T09:30:00Z",
  "timeZone": "timeZone",
  "instructions": "instructions",
  "meetingUrl": "meetingUrl",
  "capacityAtEvent": 1,
  "overageParticipants": 1,
  "questionCount": 1,
  "participantCount": 1,
  "host": {
    "id": "id",
    "name": "name",
    "email": "email",
    "image": "image"
  },
  "archivedAt": "2024-01-15T09:30:00Z"
}
```

**SDK Code**

```python
import requests

url = "https://api.taktoria.com/api/v1/dory/events/eventId/duplicate"

payload = {}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.taktoria.com/api/v1/dory/events/eventId/duplicate';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

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

func main() {

	url := "https://api.taktoria.com/api/v1/dory/events/eventId/duplicate"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.taktoria.com/api/v1/dory/events/eventId/duplicate")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.taktoria.com/api/v1/dory/events/eventId/duplicate")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.taktoria.com/api/v1/dory/events/eventId/duplicate', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.taktoria.com/api/v1/dory/events/eventId/duplicate");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.taktoria.com/api/v1/dory/events/eventId/duplicate")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```