Invite guests to company
This endpoint allows you to invite new guests to a company or resend invitations to those who haven't accepted yet. To modify permissions for already invited guests, use the /guests/permissions endpoint.
- If the guest hasn't been invited before, an invitation is sent,
- If the guest was previously invited but hasn't accepted, the original invitation is resent (ignoring any new name or permissions),
- If the guest has accepted the invitation, no new invitation is sent, but the initial invitation ID is returned, and no error is thrown.
Request
The request follows an all-or-none rule - if any guest object in the request is invalid (e.g., malformed email address), none will be invited.
Endpoint
POST https://api.woodpecker.co/rest/v2/agency/companies/{company_id}/invite_guest
Headers
x-api-key: {YOUR_API_KEY}
Content-Type: application/json
For details on how to authenticate your requests, please see the authentication guide.
Parameters
| Parameter | Required | Type | Description | 
|---|---|---|---|
| company_id | Yes | integer | Path parameter - the ID of the company to which a guest will be invited | 
Body
{
  "guests": [
    {
      "name": "Michael Scott",
      "email": "michael@dundermifflin.com",
      "guest_permissions": []
    },
    {
      "name": "Jimothy Halpert",
      "email": "jimothy@dundermifflin.com",
      "guest_permissions": ["mailboxes"]
    }
  ]
}
Body schema
| Field | Type | Required | Description | 
|---|---|---|---|
| guests | array[object] | Yes | A list of guests to invite | 
| └─ [].name | string | Yes | Full name of the invited guest | 
| └─ [].email | string | Yes | Guest's email address. It will be used as their login | 
| └─ [].guest_permissions | array[string]/null | No | mailboxes- allows guests to add/remove their email accounts | 
info
You can invite up to 10 guests with one request
Request samples
Invite guests
- cURL
- Python
- Java
- Node.js
- PHP
curl --request POST \
  --url "https://api.woodpecker.co/rest/v2/agency/companies/{company_id}/invite_guest" \
  --header "x-api-key: {YOUR_API_KEY}" \
  --header "Content-Type: application/json" \
  --data '{
    "guests": [
      {
        "name": "Michael Scott",
        "email": "michael@dundermifflin.com",
        "guest_permissions": []
      },
      {
        "name": "Jimothy Halpert",
        "email": "jimothy@dundermifflin.com",
        "guest_permissions": ["mailboxes"]
      }
    ]
  }'
import requests
def invite_guest(company_id, guests):
  url = f"https://api.woodpecker.co/rest/v2/agency/companies/{company_id}/invite_guest"
  headers = {
    "x-api-key": "{YOUR_API_KEY}",
    "Content-Type": "application/json"
  }
  data = {
    "guests": guests
  }
  
  response = requests.post(url, headers=headers, json=data)
  if response.status_code == 200:
    return response.json()
  else:
    raise Exception(f"POST request failed: {response.status_code}, {response.text}")
if __name__ == "__main__":
  try:
    company_id = 123  # Example company ID
    guests = [
      {
        "name": "Michael Scott",
        "email": "michael@dundermifflin.com",
        "guest_permissions": []
      },
      {
        "name": "Jimothy Halpert",
        "email": "jimothy@dundermifflin.com",
        "guest_permissions": ["mailboxes"]
      }
    ]
    data = invite_guest(company_id, guests)
    print("POST response:", data)
  except Exception as e:
    print("Error:", e)
public class WoodpeckerApiClient {
  private static final String API_KEY = "{YOUR_API_KEY}";
  public static void main(String[] args) {
    int companyId = 123; // Example company ID
    inviteGuest(companyId);
  }
  public static void inviteGuest(int companyId) {
    try {
      String url = "https://api.woodpecker.co/rest/v2/agency/companies/" + companyId + "/invite_guest";
      String jsonData = "{"
        + "\"guests\": ["
        + "{"
        + "\"name\": \"Michael Scott\","
        + "\"email\": \"michael@dundermifflin.com\","
        + "\"guest_permissions\": []"
        + "},"
        + "{"
        + "\"name\": \"Jimothy Halpert\","
        + "\"email\": \"jimothy@dundermifflin.com\","
        + "\"guest_permissions\": [\"mailboxes\"]"
        + "}"
        + "]"
        + "}";
      java.net.http.HttpClient client = java.net.http.HttpClient.newHttpClient();
      java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
        .uri(new java.net.URI(url))
        .header("x-api-key", API_KEY)
        .header("Content-Type", "application/json")
        .POST(java.net.http.HttpRequest.BodyPublishers.ofString(jsonData))
        .build();
      java.net.http.HttpResponse<String> response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
      if (response.statusCode() == 200) {
        System.out.println("POST response: " + response.body());
      } else {
        System.err.println("POST request failed: " + response.statusCode());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
const axios = require('axios');
async function inviteGuest(companyId, guests) {
  const url = `https://api.woodpecker.co/rest/v2/agency/companies/${companyId}/invite_guest`;
  const headers = {
    'x-api-key': '{YOUR_API_KEY}',
    'Content-Type': 'application/json'
  };
  const data = { guests: guests };
  try {
    const response = await axios.post(url, data, { headers });
    if (response.status === 200) {
      console.log('POST response:', response.data);
    } else {
      console.error('POST request failed:', response.status);
    }
  } catch (error) {
    console.error('POST request failed:', error.response ? error.response.status : error.message);
  }
}
(async () => {
  const companyId = 123; // Example company ID
  const guests = [
    {
      name: "Michael Scott",
      email: "michael@dundermifflin.com",
      guest_permissions: []
    },
    {
      name: "Jimothy Halpert",
      email: "jimothy@dundermifflin.com",
      guest_permissions: ["mailboxes"]
    }
  ];
  await inviteGuest(companyId, guests);
})();
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client([
  'base_uri' => 'https://api.woodpecker.co/rest/v2/',
  'headers'  => [
    'x-api-key'     => getenv('WOODPECKER_API_KEY'),
    'Content-Type'  => 'application/json',
  ],
]);
$companyId = '{company_id}';
try {
  $response = $client->post("agency/companies/{$companyId}/invite_guest", [
    'json' => [
      'guests' => [
        [
          'name' => 'Michael Scott',
          'email' => 'michael@dundermifflin.com',
          'guest_permissions' => [],
        ],
        [
          'name' => 'Jimothy Halpert',
          'email' => 'jimothy@dundermifflin.com',
          'guest_permissions' => ['mailboxes'],
        ],
      ],
    ],
  ]);
  echo $response->getStatusCode(), "\n";
  echo $response->getBody(), "\n";
} catch (RequestException $e) {
  echo "Error: ", $e->getMessage(), "\n";
  if ($e->hasResponse()) {
    echo $e->getResponse()->getBody(), "\n";
  }
}
Response
Response examples
- 200
- 400
- 401
- 404
- 500
A list of invited guests
{
  "guests": [
    {
      "invitation_id": 45678,
      "name": "Michael Scott",
      "email": "michael@dundermifflin.com",
      "guest_permissions": []
    },
    {
      "invitation_id": 45679,
      "name": "Jimothy Halpert",
      "email": "jimothy@dundermifflin.com",
      "guest_permissions": ["mailboxes"]
    }
  ]
}
Body schema
| Field | Type | Description | 
|---|---|---|
| guests | array[object] | List of invited guests | 
| └─ [].invitation_id | integer | A unique invitation ID, distinct from the user ID. If a guest has already been invited, the ID of the initial invitation is returned. If the guest hasn't accepted the invite yet, it will be resent | 
| └─ [].name | string | Full name of the invited guest | 
| └─ [].email | string | Guest's email address. It will be used as their login | 
| └─ [].guest_permissions | array[string] | List of guest permissions. Empty array if no permissions were granted | 
Malformed request syntax
{
  "title": "Bad request",
  "status": 400,
  "detail": "Guest name must not be blank." | "Value of guests is incorrect." | "Guest email must not be blank." | "You must invite at least one guest." | "Value of guests is incorrect. Value of guest_permissions is incorrect." | "Guest email 'email.com' is not valid email address.",
  "timestamp": "2025-03-05 17:57:00"
}
Body schema
| Field | Type | Description | 
|---|---|---|
| title | string | A short title describing the error | 
| status | integer | The HTTP status code | 
| detail | string | A detailed message explaining the error | 
| timestamp | string | The timestamp when the error occurred, YYYY-MM-DD HH:MM:SSUTC | 
An issue with authorization. Please review the authorization guide
{
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid api key",
  "timestamp": "2025-03-05 17:57:00"
}
Body schema
| Field | Type | Description | 
|---|---|---|
| title | string | A short title describing the error | 
| status | integer | The HTTP status code | 
| detail | string | A detailed message explaining the error | 
| timestamp | string | The timestamp when the error occurred, YYYY-MM-DD HH:MM:SSUTC | 
The requested company does not exists, is inactive, or the request URL is incorrect
{
  "title": "Not Found",
  "status": 404,
  "detail": "Requested resource does not exist",
  "timestamp": "2025-03-05 17:57:00"
}
Body schema
| Field | Type | Description | 
|---|---|---|
| title | string | A short title describing the error | 
| status | integer | The HTTP status code | 
| detail | string | A detailed message explaining the error | 
| timestamp | string | The timestamp when the error occurred, YYYY-MM-DD HH:MM:SSUTC | 
Unexpected error, please try again later
{
  "title": "Internal server error",
  "status": 500,
  "detail": "An unexpected error has occurred. Please try again later.",
  "timestamp": "2025-03-05 17:57:00"
}
Body schema
| Field | Type | Description | 
|---|---|---|
| title | string | A short title describing the error | 
| status | integer | The HTTP status code | 
| detail | string | A detailed message explaining the error | 
| timestamp | string | The timestamp when the error occurred, YYYY-MM-DD HH:MM:SSUTC |