API Response Structures
This document details the actual JSON response structures returned by the Sharokey API for all SDKs (Python, JavaScript, CLI), based on the Laravel API implementation.
Common Response Format
All API methods return JSON dictionaries with this structure from ApiResponse
trait:
{
"success": boolean,
"message": "string (optional)",
"data": object | array,
"meta": {
"version": "v1",
"timestamp": "2024-01-15T10:30:00.000000Z"
}
}
Secret Operations
Create Secret Response
Returned by client.create()
(from SecretController@store
lines 282-302):
{
"success": true,
"message": "Secret created successfully",
"data": {
"slug": "ABC123XY",
"description": "Database credentials",
"message": "Handle with care",
"creator": "[email protected]",
"maximum_views": 3,
"current_views": 0,
"expires_in_hours": 24,
"expiration": "2024-01-16T10:30:00.000000Z",
"has_password": true,
"has_captcha": false,
"has_otp": false,
"has_ip_restriction": true,
"has_geo_restriction": false,
"has_attachments": true,
"attachments_count": 2,
"is_expired": false,
"status": "active",
"access_url": "https://app.sharokey.com/ABC123XY",
"created_at": "2024-01-15T10:30:00.000000Z"
},
"meta": {
"version": "v1",
"timestamp": "2024-01-15T10:30:00.000000Z"
}
}
Get Secret Response
Returned by client.get(slug)
(from SecretController@show
lines 338-363):
{
"success": true,
"data": {
"slug": "ABC123XY",
"description": "Database credentials",
"message": "Handle with care",
"creator": "[email protected]",
"maximum_views": 3,
"current_views": 1,
"expiration": "2024-01-16T10:30:00.000000Z",
"has_password": true,
"has_attachments": true,
"attachments": [
{
"name": "contract.pdf"
},
{
"name": "specifications.docx"
}
],
"captcha": false,
"otp_type": null,
"ip_whitelist": "192.168.1.0/24",
"geolocation": null,
"is_expired": false,
"status": "active",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T16:15:00.000000Z"
},
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
List Secrets Response
Returned by client.list()
, client.search()
, client.get_active_secrets()
(from SecretController@index
lines 125-129):
{
"success": true,
"count": 42,
"secrets": [
{
"slug": "ABC123XY",
"description": "Database credentials",
"message": "Handle with care",
"creator": "[email protected]",
"maximum_views": 1,
"current_views": 0,
"expires_in_hours": 24,
"expiration": "2024-01-16T10:30:00.000000Z",
"has_password": false,
"has_captcha": false,
"has_otp": false,
"has_ip_restriction": false,
"has_geo_restriction": false,
"has_attachments": false,
"attachments_count": 0,
"is_expired": false,
"status": "active",
"created_at": "2024-01-15T10:30:00.000000Z"
},
{
"slug": "XYZ789AB",
"description": "API credentials",
"message": "Valid until project end",
"creator": "[email protected]",
"maximum_views": 5,
"current_views": 2,
"expires_in_hours": 48,
"expiration": "2024-01-17T10:30:00.000000Z",
"has_password": true,
"has_captcha": false,
"has_otp": true,
"has_ip_restriction": false,
"has_geo_restriction": true,
"has_attachments": true,
"attachments_count": 1,
"is_expired": false,
"status": "active",
"created_at": "2024-01-15T08:45:00.000000Z"
}
],
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Delete Secret Response
Returned by client.delete(slug)
(from SecretController@destroy
line 484):
{
"success": true,
"message": "Secret deleted successfully",
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Statistics
Statistics Response
Returned by client.stats()
(from SecretController@stats
lines 501-533):
{
"success": true,
"message": "Secrets statistics retrieved successfully",
"data": {
"total_secrets": 125,
"active_secrets": 48,
"expired_secrets": 77,
"total_views": 892,
"secrets_with_password": 23,
"secrets_created_today": 5,
"secrets_created_this_week": 18,
"secrets_created_this_month": 47
},
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Secret Requests
Note: SecretRequestController structures will be documented separately based on the actual controller implementation.
Error Responses
Validation Error (422)
From ApiResponse@validationErrorResponse
:
{
"success": false,
"message": "Validation failed",
"errors": {
"content": ["Content is required and cannot be empty"],
"expiration_hours": ["The expiration hours must be between 1 and 1000"],
"maximum_views": ["The maximum views must be between 1 and 10"]
},
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Authentication Error (401)
{
"success": false,
"message": "Unauthorized",
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Forbidden Error (403)
{
"success": false,
"message": "Insufficient permissions to create secrets",
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Not Found Error (404)
{
"success": false,
"message": "Secret not found",
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Server Error (500)
{
"success": false,
"message": "Failed to create secret",
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Quota Exceeded (429)
{
"success": false,
"message": "You have reached the maximum allowed secrets for your current plan.",
"meta": {
"version": "v1",
"timestamp": "2024-01-15T17:30:00.000000Z"
}
}
Usage Examples
Accessing Response Data
# Create secret
response = await client.create("My secret", 24, 1)
if response['success']:
secret_data = response['data']
share_url = secret_data['access_url']
print(f"Secret created: {share_url}")
# List secrets
response = await client.list(limit=10)
if response['success']:
total_count = response['count']
secrets = response['secrets']
print(f"Found {total_count} total secrets")
for secret in secrets:
views_info = f"{secret['current_views']}/{secret['maximum_views']}"
status = secret['status']
print(f"- {secret['slug']}: {secret['description']} ({views_info} views, {status})")
# Get statistics
response = await client.stats()
if response['success']:
stats = response['data']
print(f"Total: {stats['total_secrets']}")
print(f"Active: {stats['active_secrets']}")
print(f"Today: {stats['secrets_created_today']}")
# Handle errors
try:
response = await client.create("", 24, 1) # Empty content
except ValidationError as e:
print(f"Validation error: {e}")
# The actual API response would contain validation details in 'errors' field
Field Descriptions
Secret Fields
Field | Type | Description |
---|---|---|
slug | string | Unique 8-character secret identifier |
description | string|null | User-provided description (max 255 chars) |
message | string|null | Message shown to secret viewer (max 255 chars) |
creator | string | Email of creator or "API" for company tokens |
maximum_views | int|null | Maximum allowed views (1-10) |
current_views | int | Number of times secret has been viewed |
expires_in_hours | int | Hours until expiration (1-1000) |
expiration | string|null | ISO 8601 expiration timestamp |
has_password | boolean | Whether secret has password protection |
has_captcha | boolean | Whether secret requires CAPTCHA |
has_otp | boolean | Whether secret requires OTP verification |
has_ip_restriction | boolean | Whether secret has IP whitelist |
has_geo_restriction | boolean | Whether secret has geolocation restriction |
has_attachments | boolean | Whether secret has file attachments |
attachments_count | int | Number of attached files |
is_expired | boolean | Whether secret is expired |
status | string | "active" or "expired" |
access_url | string | Full URL to access the secret |
created_at | string | ISO 8601 creation timestamp |
All response structures are based on the actual Laravel API implementation and reflect the real JSON responses from the Sharokey API. 📊