Skip to main content
All issuer endpoints require authentication with ROLE_ISSUER. Access the issuer login at /login/issuer.

Dashboard

GET /issuer

Displays the main issuer dashboard with person search and document upload capabilities. Authentication: Required (ROLE_ISSUER)
personId
Long
Optional person ID to load person details and documents
Response: HTML view Model Attributes:
  • issuer: Current issuing entity
  • idTypes: Available ID types
  • person: Person entity (if personId provided)
  • personDocs: List of person’s documents
  • allowedDocs: Document definitions allowed for this issuer
Reference: IssuerController.java:90

POST /issuer/search

Searches for a person by identification type and number. Authentication: Required (ROLE_ISSUER)
idType
IdType
required
Type of identification (CC, TI, CE, etc.)
idNumber
string
required
Identification number
Response: Redirect to /issuer?personId={id} if found Error Response: Redirect to /issuer with error message Reference: IssuerController.java:131
curl -X POST https://api.example.com/issuer/search \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "idType=CC&idNumber=1234567890"

Document Upload

POST /issuer/upload

Uploads a document for a person. Only PDF files are accepted. Authentication: Required (ROLE_ISSUER)
PDF Validation: Files must:
  • Have .pdf extension
  • Have application/pdf MIME type
  • Begin with %PDF signature
Documents failing validation will be rejected.
personId
Long
required
ID of the person
documentId
Long
required
Document definition ID (must be allowed for this issuer)
status
string
required
Document status (VIGENTE, VENCIDO, etc.)
issueDate
LocalDate
Document issue date (optional)
expiryDate
LocalDate
Document expiry date (optional)
file
MultipartFile
required
PDF file to upload
Response: Redirect to /issuer?personId={personId} with success/error message Initial Status: Documents are created with PENDING review status Reference: IssuerController.java:152
curl -X POST https://api.example.com/issuer/upload \
  -F "personId=123" \
  -F "documentId=456" \
  -F "status=VIGENTE" \
  -F "issueDate=2024-01-15" \
  -F "[email protected]"

Access Requests

GET /issuer/access-requests

Lists all access requests created by the authenticated issuer. Authentication: Required (ROLE_ISSUER)
error
string
Optional error message to display
Response: HTML view with request list Model Attributes:
  • requests: List of AccessRequest entities for this issuer
  • ccRequestsSignal: Signal string for detecting changes
Request States:
  • PENDIENTE: Awaiting user decision
  • APROBADA: Approved by user
  • RECHAZADA: Rejected by user
  • EXPIRADA: Expired without decision
Reference: IssuerAccessRequestController.java:99

GET /issuer/access-requests/signal

Returns a lightweight signal for detecting changes in access requests without full page reload. Authentication: Required (ROLE_ISSUER) Response: JSON
ok
boolean
Success indicator
signal
string
Signal string (format: total|pending|approved|rejected|expired|maxId|maxRequestedAt|maxDecidedAt)
Usage: Frontend polling to detect new responses from users Reference: IssuerAccessRequestController.java:128

GET /issuer/access-requests/new

Displays the form for creating a new access request. Authentication: Required (ROLE_ISSUER)
idType
string
Pre-filled ID type (optional)
idNumber
string
Pre-filled ID number (optional)
Response: HTML form view Reference: IssuerAccessRequestController.java:149

POST /issuer/access-requests/search

Searches for a person to create an access request. Authentication: Required (ROLE_ISSUER)
idType
string
required
ID type
idNumber
string
required
ID number
Response: HTML view with person and their approved documents Reference: IssuerAccessRequestController.java:169

POST /issuer/access-requests

Creates a new access request for consulting person documents. Authentication: Required (ROLE_ISSUER)
personId
Long
required
Person ID
purpose
string
required
Purpose/reason for the access request
personDocumentIds
List<Long>
required
List of person document IDs to request access to (at least one required)
Response: Redirect to /issuer/access-requests on success Validation:
  • At least one document must be selected
  • Documents must be approved
  • Documents must belong to the specified person
Reference: IssuerAccessRequestController.java:234
curl -X POST https://api.example.com/issuer/access-requests \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "personId=123&purpose=Verification&personDocumentIds=456&personDocumentIds=789"

Document Viewing (Approved Requests)

Document viewing is only available when:
  1. The access request is in APROBADA status
  2. The request belongs to the authenticated issuer
  3. The document is included in the request items
  4. The signed URL is valid and not expired

HEAD /issuer/access-requests//documents//view

Checks if a document can be viewed without transferring the file. Authentication: Required (ROLE_ISSUER)
requestId
Long
required
Access request ID
personDocumentId
Long
required
Person document ID
exp
Long
required
URL expiration timestamp (epoch seconds)
sig
string
required
HMAC signature of the signed URL
Success Response (200): Document can be viewed Error Response (410): Request expired or not approved
  • Header: X-CCDigital-Error with encoded error message
Reference: IssuerAccessRequestController.java:321

GET /issuer/access-requests//documents//view

Views a document from an approved access request (inline display). Authentication: Required (ROLE_ISSUER)
requestId
Long
required
Access request ID
personDocumentId
Long
required
Person document ID
exp
Long
required
URL expiration timestamp (epoch seconds)
sig
string
required
HMAC signature
Response: File resource with Content-Disposition: inline Audit: Records DOC_VIEW_GRANTED event on blockchain Reference: IssuerAccessRequestController.java:293

GET /issuer/access-requests//documents//download

Downloads a document from an approved access request. Authentication: Required (ROLE_ISSUER)
requestId
Long
required
Access request ID
personDocumentId
Long
required
Person document ID
exp
Long
required
URL expiration timestamp
sig
string
required
HMAC signature
Response: File resource with Content-Disposition: attachment Audit: Records DOC_DOWNLOAD_GRANTED event on blockchain Reference: IssuerAccessRequestController.java:361

GET /issuer/access-requests//documents//block

Retrieves blockchain traceability metadata for a document. Authentication: Required (ROLE_ISSUER)
requestId
Long
required
Access request ID
personDocumentId
Long
required
Person document ID
exp
Long
required
URL expiration timestamp
sig
string
required
HMAC signature
Response: JSON payload
requestId
Long
Access request ID
personDocumentId
Long
Person document ID
network
string
Blockchain network (Fabric)
blockReference
string
Blockchain block reference
documentTitle
string
Document title
issuingEntity
string
Issuing entity name
status
string
Document status
createdAtHuman
string
Human-readable creation timestamp
sizeHuman
string
Human-readable file size
fileName
string
Original file name
filePath
string
File system path
Reference: IssuerAccessRequestController.java:387

Security

All issuer endpoints are protected by:
  • Role requirement: ROLE_ISSUER
  • Session validation: App instance ID check
  • CSRF protection: Enabled for POST requests
  • Signed URLs: Document access uses HMAC-signed URLs with expiration

Login

Endpoint: /login/issuer Method: POST Form Parameters:
  • username: Email (case-insensitive)
  • password: User password
Success: Redirects to /issuer Failure: Redirects to /login/issuer?error=true

Logout

Endpoint: /issuer/logout Method: POST Response: Redirects to /login/issuer?logout=true

Signed URL Format

Document viewing and download URLs use HMAC-SHA256 signatures:
/issuer/access-requests/{requestId}/documents/{docId}/view?exp={timestamp}&sig={signature}
Parameters:
  • exp: Unix timestamp when URL expires
  • sig: HMAC-SHA256 signature of the URL path and expiration
TTL: Configured via app.security.signed-urls.ttl-seconds (default: 300 seconds) Secret: Configured via APP_SECURITY_SIGNED_URLS_SECRET environment variable

Session Management

GET /issuer/session/keepalive

Keeps the issuer session alive during active UI interaction. Authentication: Required (ROLE_ISSUER) Response: 204 No Content Usage: Called periodically by frontend to prevent session timeout during active use. Reference: SessionActivityController.java:30

GET /issuer/session/expire

Explicitly expires the issuer session due to client-detected inactivity. Authentication: Required (ROLE_ISSUER) Response: 204 No Content Behavior:
  • Invalidates HTTP session
  • Clears Spring Security context
Reference: SessionActivityController.java:55

Build docs developers (and LLMs) love