امتثال
واجهة البرمجة

Orgs

Create Org

POST
/v1/orgs

Create a new organisation. The caller becomes the owner.

Fails with 409 if the caller already has an active org membership. Fails with 409 if the slug is already taken. Fails with 422 if the slug format is invalid.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Request Body

application/json
  1. body
name*Name
Length2 <= length <= 200
slug*Slug
Length3 <= length <= 64

Response Body

Successful Response

application/json
  1. response
created_at*Created At
Formatdate-time
is_activated?Is Activated
Defaultfalse
name*Name
org_id*Org Id
Formatuuid
slug*Slug
your_role?string|null
curl -X POST 'https://api.aisc.sa/v1/orgs' \  -H 'Content-Type: application/json' \  -d '{  "name": "string",  "slug": "string"}'
{  "created_at": "2019-08-24T14:15:22Z",  "is_activated": false,  "name": "string",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "slug": "string",  "your_role": "string"}

Accept Invitation

POST
/v1/orgs/invitations/accept

Accept an invitation as the authenticated user.

Single-use (pending->accepted under FOR UPDATE), expiry- and revoke-checked, email-match guarded (the accepting user's email must equal the invited email), and one-active-org enforced. Bumps role_version so the joiner's next token re-resolves org_id.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Request Body

application/json
  1. body
token*Token
Length8 <= length <= 128

Response Body

Successful Response

application/json
  1. response
email*Email
joined_at*Joined At
Formatdate-time
left_at?|null
member_id*Member Id
Formatuuid
role*Role
user_id*User Id
Formatuuid
curl -X POST 'https://api.aisc.sa/v1/orgs/invitations/accept' \  -H 'Content-Type: application/json' \  -d '{  "token": "stringst"}'
{  "email": "string",  "joined_at": "2019-08-24T14:15:22Z",  "left_at": "2019-08-24T14:15:22Z",  "member_id": "435a4844-006a-4cfc-a644-e8eb2dd2ca43",  "role": "string",  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"}

Preview Invitation

GET
/v1/orgs/invitations/preview

PUBLIC (no auth): minimal preview for the /join landing page.

Returns only {organisation_name, role, inviter, email_registered}. Any miss (bad/expired/revoked/used token) is a generic non-enumerable 404. Expired pending invites are lazily flipped to 'expired'.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Query Parameters

token*Token

Response Body

Successful Response

application/json
  1. response
email_registered*Email Registered
inviter*Inviter
organisation_name*Organisation Name
role*Role
curl -X GET 'https://api.aisc.sa/v1/orgs/invitations/preview?token=string'
{  "email_registered": true,  "inviter": "string",  "organisation_name": "string",  "role": "string"}

Get My Org

GET
/v1/orgs/me

Return the caller's active organisation. 404 if the user is solo.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Response Body

Successful Response

application/json
  1. response
created_at*Created At
Formatdate-time
is_activated?Is Activated
Defaultfalse
name*Name
org_id*Org Id
Formatuuid
slug*Slug
your_role?string|null
curl -X GET 'https://api.aisc.sa/v1/orgs/me'
{  "created_at": "2019-08-24T14:15:22Z",  "is_activated": false,  "name": "string",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "slug": "string",  "your_role": "string"}

List Invitations

GET
/v1/orgs/me/invitations

List PENDING invitations for the caller's org (never the token/hash).

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Response Body

Successful Response

application/json
  1. response
invitations*array<>
curl -X GET 'https://api.aisc.sa/v1/orgs/me/invitations'
{  "invitations": [    {      "created_at": "2019-08-24T14:15:22Z",      "email": "string",      "expires_at": "2019-08-24T14:15:22Z",      "invitation_id": "a6e6785a-3ea9-406c-b873-17eaf2ed5fc9",      "role": "string",      "status": "string"    }  ]}

Create Invitation

POST
/v1/orgs/me/invitations

Create a single-use, short-lived invite for email (registered or not).

Returns the RAW token + link ONCE (only its hash is stored). Best-effort emails the link. 409 if a pending invite for this (org, email) already exists, or if the email is already an active member of this org.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Request Body

application/json
  1. body
email*Email
Length3 <= length <= 320
role?Role
Match^(owner|admin|member|viewer)$
Default"member"

Response Body

Successful Response

application/json
  1. response
email*Email
expires_at*Expires At
Formatdate-time
invitation_id*Invitation Id
Formatuuid
invite_url*Invite Url
role*Role
token*Token
curl -X POST 'https://api.aisc.sa/v1/orgs/me/invitations' \  -H 'Content-Type: application/json' \  -d '{  "email": "string"}'
{  "email": "string",  "expires_at": "2019-08-24T14:15:22Z",  "invitation_id": "a6e6785a-3ea9-406c-b873-17eaf2ed5fc9",  "invite_url": "string",  "role": "string",  "token": "string"}

Revoke Invitation

DELETE
/v1/orgs/me/invitations/{invitation_id}

Revoke a pending invitation (immediate kill-switch).

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Path Parameters

invitation_id*Invitation Id
Formatuuid

Response Body

Successful Response

curl -X DELETE 'https://api.aisc.sa/v1/orgs/me/invitations/497f6eca-6276-4993-bfeb-53cbbbba6f08'
Empty

List Members

GET
/v1/orgs/me/members

Return paginated active member list for the caller's org.

Keyset cursor is "<joined_at_iso>:<member_id>"; pass in ?after=<cursor>. Members who have left (left_at IS NOT NULL) are excluded.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Query Parameters

limit?Limit
Default50
after?string|null

Response Body

Successful Response

application/json
  1. response
members*array<>
next_cursor?string|null
curl -X GET 'https://api.aisc.sa/v1/orgs/me/members'
{  "members": [    {      "email": "string",      "joined_at": "2019-08-24T14:15:22Z",      "left_at": "2019-08-24T14:15:22Z",      "member_id": "435a4844-006a-4cfc-a644-e8eb2dd2ca43",      "role": "string",      "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"    }  ],  "next_cursor": "string"}

Invite Member

POST
/v1/orgs/me/members

Invite an existing user (by email) to the caller's org.

The target user must already be registered. The target user must not already have an active org membership. Returns 201 {"member_id": "<uuid>"} on success.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Request Body

application/json
  1. body
email*Email
Length3 <= length <= 320
role?Role
Match^(owner|admin|member|viewer)$
Default"member"

Response Body

Successful Response

application/json
  1. response
[key: string]?any
curl -X POST 'https://api.aisc.sa/v1/orgs/me/members' \  -H 'Content-Type: application/json' \  -d '{  "email": "string"}'
{}

Patch Member

PATCH
/v1/orgs/me/members/{member_id}

Change a member's role.

Last-owner protection: if the target member is the last owner AND the new role is not 'owner', returns 409 ORG_LAST_OWNER.

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Path Parameters

member_id*Member Id
Formatuuid

Request Body

application/json
  1. body
role*Role
Match^(owner|admin|member|viewer)$

Response Body

Successful Response

application/json
  1. response
email*Email
joined_at*Joined At
Formatdate-time
left_at?|null
member_id*Member Id
Formatuuid
role*Role
user_id*User Id
Formatuuid
curl -X PATCH 'https://api.aisc.sa/v1/orgs/me/members/497f6eca-6276-4993-bfeb-53cbbbba6f08' \  -H 'Content-Type: application/json' \  -d '{  "role": "string"}'
{  "email": "string",  "joined_at": "2019-08-24T14:15:22Z",  "left_at": "2019-08-24T14:15:22Z",  "member_id": "435a4844-006a-4cfc-a644-e8eb2dd2ca43",  "role": "string",  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"}

Remove Member

DELETE
/v1/orgs/me/members/{member_id}

Soft-remove a member (sets left_at = now()).

Last-owner protection: if the target is the last owner, returns 409. The removed user reverts to solo-tenant on their next request (role_version bump forces re-login, which re-resolves org_id = None).

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Path Parameters

member_id*Member Id
Formatuuid

Response Body

Successful Response

curl -X DELETE 'https://api.aisc.sa/v1/orgs/me/members/497f6eca-6276-4993-bfeb-53cbbbba6f08'
Empty
GET
/v1/orgs/me/permissions

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Response Body

Successful Response

application/json
  1. response
ai_training*
can_change*Can Change
llm_assistant*
curl -X GET 'https://api.aisc.sa/v1/orgs/me/permissions'
{  "ai_training": {    "changed_at": "2019-08-24T14:15:22Z",    "granted": true,    "policy_version": "string"  },  "can_change": true,  "llm_assistant": {    "changed_at": "2019-08-24T14:15:22Z",    "granted": true,    "policy_version": "string"  }}
PUT
/v1/orgs/me/permissions

Authorization

BearerAuth
headerAuthorizationBearer <token>

JWT access token. Obtain via POST /v1/auth/login.

Request Body

application/json
  1. body
granted*Granted
locale*Locale
Value in"ar""en"
policy_version*Policy Version
Match^[A-Za-z0-9.+:_-]+$
Length1 <= length <= 80
purpose*Purpose
Value in"ai_training""llm_assistant"
source*Source
Value in"settings""signup"

Response Body

Successful Response

application/json
  1. response
changed_at?|null
granted*Granted
policy_version?string|null
curl -X PUT 'https://api.aisc.sa/v1/orgs/me/permissions' \  -H 'Content-Type: application/json' \  -d '{  "granted": true,  "locale": "ar",  "policy_version": "string",  "purpose": "ai_training",  "source": "settings"}'
{  "changed_at": "2019-08-24T14:15:22Z",  "granted": true,  "policy_version": "string"}