Get Public Profile by Code
Retrieve a user's public CANSKAN profile using their QR code hash.
GET /profile/{code}
Retrieve a public CANSKAN profile using the user's QR code identifier.
Base URL
https://api.canskan.com
Endpoint
GET /profile/{code}
Path Parameters
code – required, string 32-character lowercase MD5 hash associated with the user's email.
Example:
e4d909c290d0fb1ca068ffaddf22cbd0
Request
HTTP Request
GET https://api.canskan.com/profile/e4d909c290d0fb1ca068ffaddf22cbd0
Accept: application/json
Query Parameters (optional / reserved)
- fields – Comma-separated fields from
public_profileto include. - expand – Reserved for future extended data.
Response
Successful Response (200)
{
"status": "success",
"data": {
"code": "e4d909c290d0fb1ca068ffaddf22cbd0",
"type": "public_profile",
"public_profile": {
"display_name": "Harley Doyon",
"headline": "Full-stack engineer & QR identity enthusiast",
"avatar_url": "https://cdn.canskan.com/avatars/e4d909c2.png",
"bio": "I use my CANSKAN QR code to simplify forms & check-ins everywhere.",
"links": {
"website": "https://harley.dev",
"twitter": "https://twitter.com/harley",
"linkedin": "https://linkedin.com/in/harleydoyon"
},
"meta": {
"locale": "en-PH",
"timezone": "Asia/Manila"
}
},
"flags": {
"is_active": true,
"is_deletable": true,
"is_public": true
},
"created_at": "2025-11-20T09:30:00.000Z",
"updated_at": "2025-11-20T10:15:00.000Z"
}
}
Error Responses
All error responses share this structure:
{
"status": "error",
"error": {
"code": "string",
"message": "Human-readable error message.",
"details": {
"field": "optional extra info"
}
}
}
400 – Invalid Code Format
{
"status": "error",
"error": {
"code": "invalid_code_format",
"message": "The supplied profile code is not valid.",
"details": {
"expected": "32-character lowercase hex MD5 string"
}
}
}
404 – Profile Not Found
{
"status": "error",
"error": {
"code": "profile_not_found",
"message": "No public profile was found for the given code."
}
}
410 – Profile Deleted
{
"status": "error",
"error": {
"code": "profile_gone",
"message": "This profile has been deleted and is no longer available."
}
}
429 – Rate Limit Exceeded
{
"status": "error",
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Please wait before trying again."
}
}
500 – Server Error
{
"status": "error",
"error": {
"code": "internal_server_error",
"message": "An unexpected error occurred. Please try again later."
}
}
Rate Limiting
Public access to GET /profile/{code} is rate-limited.
- Limit: 60 requests per minute per IP
- The API returns the following headers with each response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1732099200
X-RateLimit-Resetis a Unix timestamp indicating when the limit resets.
If the limit is exceeded, the API returns HTTP 429 and stops serving requests until the window resets.
Usage Examples
curl
curl "https://api.canskan.com/profile/e4d909c290d0fb1ca068ffaddf22cbd0" \
-H "Accept: application/json"
JavaScript (fetch)
const code = "e4d909c290d0fb1ca068ffaddf22cbd0"
fetch(`https://api.canskan.com/profile/${code}`, {
headers: {
Accept: "application/json"
}
})
.then(async (res) => {
if (!res.ok) {
const error = await res.json()
throw error
}
return res.json()
})
.then((payload) => {
console.log("Profile:", payload.data.public_profile)
})
.catch(console.error)
Python (requests)
import requests
code = "e4d909c290d0fb1ca068ffaddf22cbd0"
url = f"https://api.canskan.com/profile/{code}"
response = requests.get(url, headers={"Accept": "application/json"})
if response.ok:
data = response.json()
print("Profile:", data["data"]["public_profile"])
else:
error = response.json()
print("Error:", error["error"]["message"])
Versioning
By default, the API uses the latest stable version.
You can optionally send:
X-Api-Version: 1
to pin the version. If omitted, the latest stable version is used.
Additional Notes
- The
codeparameter is case-sensitive and must be lowercase. - Only public profile information is returned. Users control what information is public through their account settings.
- The API supports CORS for client-side requests from any origin.
- Future versions may include pagination for extended data (e.g., activity feeds).
