Skip to content

Genway Public API (1.0.0)

Genway's API enables you to programmatically manage various aspects of your projects, prototypes, and interviews using our AI interviewer.

  • Projects - Create and manage Contextual Interviews or Prototype Testing projects.
  • Interviews - Manage and export interview data, including transcripts, summaries, audio, and video.

Genway API overview

Authentication

Genway API uses dual-header authentication for all requests to ensure secure access and proper tenant isolation.

Required Headers:

X-Api-Key: YOUR_API_KEY
X-Tenant-Id: YOUR_TENANT_UUID

Both headers are mandatory for every API call. Missing either header will result in authentication failure.

Versioning and stability

We strongly aim for backward compatibility for the documented endpoints. If backwards-incompatible changes are made, we will aim to release a new version.

  • URLs’ entry point is https://api.genway.ai/.
  • URLs are versioned https://api.genway.ai/v1/{endpoint}, e.g. https://api.genway.ai/v1/projects.

Rate limits and API status

The Genway API enforces per-IP rate limits to keep the platform responsive:

ScopeLimitEndpoints / Examples
Global throughputUp to 50 requests per minute per IPApplies to every endpoint, including Export interview video and Activate project.
Project creation10 requests per minute per IPCreate a new project (POST /projects).

When a limit is exceeded the API responds with 429 Too Many Requests, includes a Retry-After header indicating when you can resume sending requests, and returns the rate-limit payload documented in the 429 response example for endpoints such as Create a new project.

You can subscribe to our status page.

API support

If you require help you can contact our support team at support@genway.ai.

Download OpenAPI description
Languages
Servers
Production environment

https://api.genway.ai/v1/

Multi-Tenancy

Genway provides a secure tenant-based authentication system that ensures strong data isolation between customers.

Tenants

Manage tenant creation and multi-tenancy setup.

Operations

Projects

Manage your projects programmatically.

Operations

Interviews

Manage and export interview data.

Operations

Webhooks

Webhooks deliver event data to your applications as it happens, offering an alternative to frequent data polling.

  • The secret created via the /webhooks/secrets endpoint is permanent and should be stored securely in your system. This secret will serve for the verifying section.
  • The x-hook-secret is temporary and should be used only once during the confirmation process.
  • Until the webhook is confirmed, no events will be sent to the subscriber's endpoint.
Operations

Subscribing

Flow Diagram

The flow below shows the inbound nature of hook configuration. This is what is required to register your subscription.

Genway Webhooks Flow

Double Opt-In (DOI)

We use a Double Opt-In (DOI) approach for webhooks to prevent abuse, misconfigurations, and unintended subscriptions. This mechanism ensures that the webhook consumer explicitly confirms their intent to receive webhook events before we start sending them.

Listing event types

To get started, make a GET request to /webhooks/event-types to retrieve an up-to-date list of all the event types that we currently support. All event types will follow the noun.verb pattern, e.g. project.published.

Make a note of the event type you’d like to subscribe to. You’ll need this later when setting up a subscription.

Creating a secret

In order to subscribe to an event, you’ll need to first set up a secret. Secrets are used to verify the authenticity of our webhook requests to your system. It allows you to prove we have sent them and the payload hasn't been fiddled with. There is more about that in the Verifying section below.

Make a POST request to /webhooks/secrets/ with the payload below. This will create a new secret for your workspace and be returned in the response body. Keep this safe, and note that you can only have one active secret per workspace at a time.

{"workspace_id": <workspace_id>}

Subscribing to an event (Opt-In Step 1)

Next, make a POST request to /webhooks/subscriptions/ with the payload below to subscribe to your desired event.

Note. <target_url> must be use https:// and be publicly accessible i.e. not https://localhost.

{"workspace_id": <workspace_id>, "event_type": <event_type>, "target_url": <target_url>}

If successful, the endpoint will return a response that includes:

  1. An id field in the body - This is the unique identifier for your subscription.
  2. An X-Hook-Secret header - Used to confirm your intention to subscribe to the desired event type.

Make a note of both the id and the X-Hook-Secret. We’ll use these to confirm our intention to subscribe to the desired event type.

Confirming the subscription (Opt-In Step 2)

Make a POST request to /webhooks/subscriptions/<subscription_id>/ with the payload below. Replace <x-hook-secret> with the value of the X-Hook-Secret header in the previous subscription request.

{"secret": <x-hook-secret>}

If subscription confirmation is successful, you should receive a 200 status code.

Receiving

Having successfully subscribed to our desired event type, our target url will be notified each and every time the associated event is triggered. You can react to this event in any way you see fit. The response body will adhere to the following structure:

project.published

{
  "project_id": "<project_id>",
  "published_at": "<published_at>",
}
FieldDescription
project_idThe unique identifier of the project resource.
event_typeThe type of event project.published.
published_atThe timestamp when the project was published.

project.completed

{
  "project_id": "<project_id>",
  "completed_at": "<completed_at>",
}
FieldDescription
project_idThe unique identifier of the project resource.
event_typeThe type of event project.completed.
completed_atThe timestamp when the project was completed.

interview.finished

{
  "project_id": "<project_id>",
  "interview_id": "<interview_id>",
  "interviewee_id": "<interviewee_id>",
  "finished_at": "<finished_at>",
}
FieldDescription
project_idThe unique identifier of the project resource.
event_typeThe type of event interview.finished.
interview_idThe unique identifier for the interview.
interviewee_idThe unique identifier of the interviewee.
finished_atThe timestamp when the interviewee finished the interview.

Responding to events

When developing your system to handle incoming webhooks, it is crucial to respond with a 200 status code within 20 seconds to avoid timeouts and retries.

If your processing logic involves long-running tasks, it is recommended to handle these tasks asynchronously. This ensures that the webhook endpoint can quickly acknowledge receipt of the event, while the actual processing is offloaded to a separate service. By doing so, you can maintain responsiveness and reliability in your webhook handling system.

Event Error Handling

In the case of a network error or a non-200 response, our system will retry the event another 2 times.

The first retry will occur after 1 minute, and if it fails again, the second retry will occur after an additional 2 minutes with a full jitter. This approach ensures that transient issues are handled gracefully, while also preventing overwhelming the system with immediate retries.

Here is an example table with timestamps when the events will happen:

AttemptTimestampDelay
Initial2023-10-01 12:00:00-
Retry 12023-10-01 12:01:001 minute
Retry 22023-10-01 12:03:002 minutes

In this example, the initial event occurs at 12:00:00. If it fails, the first retry happens at 12:01:00, and if it fails again, the second retry happens at 12:03:00.

Idempotency and the X-Event-ID Header

X-Event-ID is added as a header to the request. It is a unique identifier assigned to each event.

  • Uniqueness: Each X-Event-ID value will be globally unique for each event that occurs.
  • Re-Delivery: Events are delivered at least once. We will redeliver events on failure due to network issues, timeouts and listener errors. The X-Event-ID will remain the same across retries.
  • Idempotent Processing: We recommend that you use the X-Event-ID to handle events in an idempotent way. If you encounter the same X-Event-ID again, simply skip and acknowledge the duplicate event rather than processing it a second time.

Handling event order with X-Timestamp

The X-Timestamp header is added to the request. It contains a UNIX timestamp indicating when the event was sent.

You can use this timestamp to determine if you are processing an out-of-order update. In some cases, you may want to ignore older events and only process the latest event.

As a webhook system, we do not guarantee the order of events. This can be affected by multiple factors such as errors sending events and retrying after a delay, where a newer event may have already been sent.

Verifying

Webhooks have been implemented to provide a measure to verify the authenticity of a payload. This helps to ensure only payloads sent by Genway are being accepted by your endpoint. Hook requests will contain two headers, X-Genway-Request-Signature and X-Genway-Request-Timestamp. The former represents signature and the latter represents a UNIX timestamp of when the request was sent.

In order to verify the signature, you can create the same SHA256 Hashed Message Authentication Code (HMAC) signature and then compare it to X-Genway-Request-Signature. To do this, sign the request body and timestamp with your secret key using SHA256 and then base64 encode the resulting digest.

Example with Python

import hmac
import hashlib
import base64
import json

SECRET = 'your_secret_key'
timestamp = request.headers.get('X-Genway-Request-Timestamp')  # from request headers
signature = request.headers.get('X-Genway-Request-Signature')  # from request headers
body = request.get_json()  # from request body

encoded_secret = SECRET.encode()
body = json.dumps(body)
calculated_signature = base64.b64encode(
    hmac.new(
        encoded_secret,
        str.encode(timestamp + body),
        hashlib.sha256
    ).digest()
)
is_valid = hmac.compare_digest(
    calculated_signature, str.encode(signature)
)
print(is_valid)

Request

Retrieve an up-to-date list of all the event types that we currently support.

Security
api_key and tenant_id
curl -i -X GET \
  https://api.genway.ai/v1/webhooks/event-types \
  -H 'X-Api-Key: YOUR_API_KEY_HERE' \
  -H 'X-Tenant-Id: YOUR_API_KEY_HERE'

Responses

List of event types retrieved successfully

Bodyapplication/jsonArray [
string
]
Response
application/json
[ "project.published" ]

Request

Create a new secret for your workspace.

Security
api_key and tenant_id
Bodyapplication/jsonrequired
workspace_idstring(uuid)
Example: "4e1b58da-06de-4173-a276-15609442c470"
curl -i -X POST \
  https://api.genway.ai/v1/webhooks/secrets \
  -H 'Content-Type: application/json' \
  -H 'X-Api-Key: YOUR_API_KEY_HERE' \
  -H 'X-Tenant-Id: YOUR_API_KEY_HERE' \
  -d '{
    "workspace_id": "4e1b58da-06de-4173-a276-15609442c470"
  }'

Responses

Secret created successfully

Bodyapplication/json
secretstring
Example: "sec_af245ede-a9d0-40b4-9ffc-a4bf11fdfebb"
Response
application/json
{ "secret": "sec_af245ede-a9d0-40b4-9ffc-a4bf11fdfebb" }

Request

Subscribe to your desired event.

Security
api_key and tenant_id
Bodyapplication/jsonrequired
workspace_idstring
Example: "4e1b58da-06de-4173-a276-15609442c470"
event_typestring
Example: "project.published"
target_urlstring(uri)
Example: "https://yourapp.com/webhook"
curl -i -X POST \
  https://api.genway.ai/v1/webhooks/subscriptions \
  -H 'Content-Type: application/json' \
  -H 'X-Api-Key: YOUR_API_KEY_HERE' \
  -H 'X-Tenant-Id: YOUR_API_KEY_HERE' \
  -d '{
    "workspace_id": "4e1b58da-06de-4173-a276-15609442c470",
    "event_type": "project.published",
    "target_url": "https://yourapp.com/webhook"
  }'

Responses

Subscription created successfully

Bodyapplication/json
idstring
Example: "subscription_123"
x_hook_secretstring
Example: "x_hook_secret_value"
Response
application/json
{ "id": "subscription_123", "x_hook_secret": "x_hook_secret_value" }

Request

Retrieve a list of all subscriptions.

Security
api_key and tenant_id
curl -i -X GET \
  https://api.genway.ai/v1/webhooks/subscriptions \
  -H 'X-Api-Key: YOUR_API_KEY_HERE' \
  -H 'X-Tenant-Id: YOUR_API_KEY_HERE'

Responses

List of subscriptions retrieved successfully

Bodyapplication/jsonArray [
idstring
Example: "subscription_123"
workspace_idstring
Example: "workspace_123"
event_typestring
Example: "project.published"
target_urlstring(uri)
Example: "https://yourapp.com/webhook"
]
Response
application/json
[ { "id": "subscription_123", "workspace_id": "workspace_123", "event_type": "project.published", "target_url": "https://yourapp.com/webhook" } ]

Request

Confirm your intention to subscribe to the desired event type.

Security
api_key and tenant_id
Path
subscription_idstringrequired

The ID of the subscription to confirm

Bodyapplication/jsonrequired
secretstring
Example: "<x-hook-secret>"
curl -i -X POST \
  'https://api.genway.ai/v1/webhooks/subscriptions/{subscription_id}' \
  -H 'Content-Type: application/json' \
  -H 'X-Api-Key: YOUR_API_KEY_HERE' \
  -H 'X-Tenant-Id: YOUR_API_KEY_HERE' \
  -d '{
    "secret": "<x-hook-secret>"
  }'

Responses

Subscription confirmed successfully

Response
No content

Request

Delete a subscription by its subscription_id.

Security
api_key and tenant_id
Path
subscription_idstringrequired

The ID of the subscription to delete

curl -i -X DELETE \
  'https://api.genway.ai/v1/webhooks/subscriptions/{subscription_id}' \
  -H 'X-Api-Key: YOUR_API_KEY_HERE' \
  -H 'X-Tenant-Id: YOUR_API_KEY_HERE'

Responses

Subscription deleted successfully

Response
No content

Errors

The Genway API uses standard HTTP response codes to indicate the success or failure of the request. Codes follow this pattern:

  • 2xx codes indicate success.
  • 4xx codes indicate a request that failed given the information provided (e.g., a required parameter was omitted).
  • 5xx codes indicate an error with Genway's platform.