Start here
Accept an invitation
POST
/v1/studio/invites/accepton https://api.auray.ai/v1Join the project an invitation is to, as the role it gives.
Join the project an invitation is to, as the role it gives. An email invitation opens only for the account with its address (invite_not_yours). A project seats as many people as its limits.members says, its owner counted — its owner's plan's figure; past it the invitation is refused studio_limit_reached and is not spent. Answers the project as its new member reads it. Takes a key holding studio:write — Account offers it unticked — or the desktop's own session key. Spends nothing.
#Authentication
Authorization: Bearer auray_sk_… — a key with the scope the route names.
#Request
#Body
application/json, required.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
token | string | yes | — | The token the invitation's link carries in its fragment (#studio-invite=<token>). |
#Example request
curl -X POST https://api.auray.ai/v1/studio/invites/accept \
-H "Authorization: Bearer $AURAY_API_KEY" \
-H "content-type: application/json" \
-d '{
"token": "…"
}'const res = await fetch("https://api.auray.ai/v1/studio/invites/accept", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AURAY_API_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
"token": "…"
}),
});
console.log(await res.json());import os, requests
r = requests.post(
"https://api.auray.ai/v1/studio/invites/accept",
headers={"Authorization": f"Bearer {os.environ['AURAY_API_KEY']}"},
json={
"token": "…"
},
)
r.raise_for_status()
print(r.json())package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body := []byte(`{
"token": "…"
}`)
req, err := http.NewRequest("POST", "https://api.auray.ai/v1/studio/invites/accept", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AURAY_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}<?php
$ch = curl_init("https://api.auray.ai/v1/studio/invites/accept");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("AURAY_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"token" => "…",
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $response, PHP_EOL;require "net/http"
require "json"
uri = URI("https://api.auray.ai/v1/studio/invites/accept")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("AURAY_API_KEY")}"
req["Content-Type"] = "application/json"
req.body = {
"token" => "…"
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code, res.bodyimport 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 = """
{
"token": "…"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.auray.ai/v1/studio/invites/accept"))
.header("Authorization", "Bearer " + System.getenv("AURAY_API_KEY"))
.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());
}
}using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AURAY_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.auray.ai/v1/studio/invites/accept");
var body = """
{
"token": "…"
}
""";
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");#Responses
#200 OK
OK.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
object | string | yes | — | One of "project". |
id | string | yes | — | |
name | string | yes | — | 0 to 80 characters. |
slug | string | yes | — | The address segment its links carry; unique among the owner's projects. 3 to 60 characters. |
description | string | yes | — | 0 to 140 characters. May be null. |
cover | object or null | yes | — | |
cover_item_id | string | yes | — | May be null. |
access | string | yes | — | private is the only access in this release. One of "private", "team". |
role | string | yes | — | Your own role in the project. One of "owner", "admin", "collaborator", "viewer". |
can | string[] | yes | — | What your role lets you do here; anything else is refused role_forbidden. |
counts | object | yes | — | |
counts.items | integer | yes | — | Every item not in the Trash. |
counts.generations | integer | yes | — | |
counts.uploads | integer | yes | — | |
counts.elements | integer | yes | — | |
counts.folders | integer | yes | — | |
counts.trashed | integer | yes | — | |
limits | object | yes | — | What it may hold: the figures in force of its OWNER's plan (studio.max_items, studio.max_canvases, studio.max_members), whoever reads it — each told only to a role that can add against it, null to every other reader. A figure moved lower refuses the next one past it (studio_limit_reached, whose max is the same number) and takes nothing away, so a count above it is a project that held more before. |
limits.items | integer | yes | — | Items it may hold, the Trash counted. Null unless your role may generate, upload or edit items. 1 to …. May be null. |
limits.canvases | integer | yes | — | Canvases it may hold. Null unless your role may edit canvases. 1 to …. May be null. |
limits.members | integer | yes | — | People it may seat, its owner counted. Null unless your role manages members. 1 to …. May be null. |
plan | object | yes | — | What its OWNER's plan lets happen in it, whoever reads it — each bit told only to a reader it binds, null to every other, as limits is. open false is a read-only project: its owner's plan does not include Cinema Studio, so nothing can be added or changed in it, and every such write answers studio_not_in_plan; opening and downloading everything, removing things and handing the project over still work, and can stays your role's list. |
plan.open | boolean | yes | — | Whether anything can be added or changed here: false in a read-only project. Null only to a reader who is no member. May be null. |
plan.calls | boolean | yes | — | Whether a call can be held here: its owner's plan includes Cinema Studio and calls, and seats a team. False, a join answers studio_not_in_plan. Null unless your role may join calls. May be null. |
plan.publish | boolean | yes | — | Whether the project may be published, or its publication updated: its owner's plan includes Cinema Studio and publishing. Withdrawing a publication never asks. Null unless you own it. May be null. |
bytes | integer | yes | — | What its kept files take, the Trash included — what deleting it frees. |
created_at | string | yes | — | |
updated_at | string | yes | — | |
request_id | string | no | — | Mirrored in the X-Request-Id header. |
Headers:
| Header | Description |
|---|---|
RateLimit-Limit | Burst capacity. |
RateLimit-Remaining | |
RateLimit-Reset | Seconds until refill. |
X-RateLimit-Limit | |
X-RateLimit-Remaining | |
X-RateLimit-Reset | Unix seconds. The X- spelling is what client libraries read. |
X-Request-Id |
#400 Bad Request
#401 Unauthorized
#403 Forbidden
#409 Conflict
#410 Gone
#413 Payload Too Large
#429 Too Many Requests
#500 Internal Server Error
#503 Service Unavailable
#Status codes
| Status | Meaning |
|---|---|
200 | OK. |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
409 | Conflict |
410 | Gone |
413 | Payload Too Large |
429 | Too Many Requests |
500 | Internal Server Error |
503 | Service Unavailable |
Every refusal names its code, and every code is explained at Errors.